128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer#!/bin/bash 228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# 328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# findmisopt 428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# 528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# This is a quick and dirty hack to potentially find a misoptimization 628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# problem. Mostly its to work around problems in bugpoint that prevent 728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# it from finding a problem unless the set of failing optimizations are 828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# known and given to it on the command line. 928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# 1018d52f2fb551c295bbce4c7d7357f4050b06e926Duncan Sands# Given a bitcode file that produces correct output (or return code), 1128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# this script will run through all the optimizations passes that gccas 1228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# uses (in the same order) and will narrow down which optimizations 1328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# cause the program either generate different output or return a 1428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# different result code. When the passes have been narrowed down, 15a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer# bugpoint is invoked to further refine the problem to its origin. If a 16a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer# release version of bugpoint is available it will be used, otherwise 17a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer# debug. 1828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# 1928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# Usage: 2028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# findmisopt bcfile outdir progargs [match] 2128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# 2228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# Where: 2328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# bcfile 2418d52f2fb551c295bbce4c7d7357f4050b06e926Duncan Sands# is the bitcode file input (the unoptimized working case) 2528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# outdir 2628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# is a directory into which intermediate results are placed 2728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# progargs 2828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# is a single argument containing all the arguments the program needs 292232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencer# proginput 302232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencer# is a file name from which stdin should be directed 31a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer# match 3228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# if specified to any value causes the result code of the program to 3328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# be used to determine success/fail. If not specified success/fail is 3428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# determined by diffing the program's output with the non-optimized 3528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# output. 3628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# 37e4d8f33b0f1dfe0e6b2741c6936b26f21031ac90Reid Spencerif [ "$#" -lt 3 ] ; then 38e4d8f33b0f1dfe0e6b2741c6936b26f21031ac90Reid Spencer echo "usage: findmisopt bcfile outdir progargs [match]" 39e4d8f33b0f1dfe0e6b2741c6936b26f21031ac90Reid Spencer exit 1 40e4d8f33b0f1dfe0e6b2741c6936b26f21031ac90Reid Spencerfi 41e4d8f33b0f1dfe0e6b2741c6936b26f21031ac90Reid Spencer 42a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencerdir="${0%%/utils/findmisopt}" 43a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencerif [ -x "$dir/Release/bin/bugpoint" ] ; then 44a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer bugpoint="$dir/Release/bin/bugpoint" 45a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencerelif [ -x "$dir/Debug/bin/bugpoint" ] ; then 46a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer bugpoint="$dir/Debug/bin/bugpoint" 47a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencerelse 48a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer echo "findmisopt: bugpoint not found" 49a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer exit 1 50a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencerfi 51a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer 5228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerbcfile="$1" 5328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spenceroutdir="$2" 5428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerargs="$3" 552232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencerinput="$4" 562232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencerif [ ! -f "$input" ] ; then 572232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencer input="/dev/null" 582232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencerfi 592232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencermatch="$5" 6028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencername=`basename $bcfile .bc` 6128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerll="$outdir/${name}.ll" 6228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencers="$outdir/${name}.s" 6328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerprog="$outdir/${name}" 6428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerout="$outdir/${name}.out" 6528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spenceroptbc="$outdir/${name}.opt.bc" 6628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spenceroptll="$outdir/${name}.opt.ll" 6728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spenceropts="$outdir/${name}.opt.s" 6828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spenceroptprog="$outdir/${name}.opt" 6928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spenceroptout="$outdir/${name}.opt.out" 70f8463a38bf04b822d009e9e4eaae2e4a3c930da4Reid Spencerldflags="-lstdc++ -lm -ldl -lc" 7128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 7228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerecho "Test Name: $name" 7328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerecho "Unoptimized program: $prog" 7428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerecho " Optimized program: $optprog" 7528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 76f6101ac7bcb06ec3488bd5afab38f20ae6855e35Reid Spencer# Define the list of optimizations to run. This comprises the same set of 77f6101ac7bcb06ec3488bd5afab38f20ae6855e35Reid Spencer# optimizations that opt -std-compile-opts and gccld run, in the same order. 78f6101ac7bcb06ec3488bd5afab38f20ae6855e35Reid Spenceropt_switches=`llvm-as < /dev/null -o - | opt -std-compile-opts -disable-output -debug-pass=Arguments 2>&1 | sed 's/Pass Arguments: //'` 7975338097c786eea1c461e744a2c45af78f56286fMichael J. Spencerall_switches="$opt_switches" 80f6101ac7bcb06ec3488bd5afab38f20ae6855e35Reid Spencerecho "Passes : $all_switches" 81f6101ac7bcb06ec3488bd5afab38f20ae6855e35Reid Spencer 82024409995684ed37250a0d6dec4956316368a42aReid Spencer# Create output directory if it doesn't exist 83024409995684ed37250a0d6dec4956316368a42aReid Spencerif [ -f "$outdir" ] ; then 84024409995684ed37250a0d6dec4956316368a42aReid Spencer echo "$outdir is not a directory" 85024409995684ed37250a0d6dec4956316368a42aReid Spencer exit 1 86024409995684ed37250a0d6dec4956316368a42aReid Spencerfi 87024409995684ed37250a0d6dec4956316368a42aReid Spencer 88024409995684ed37250a0d6dec4956316368a42aReid Spencerif [ ! -d "$outdir" ] ; then 89024409995684ed37250a0d6dec4956316368a42aReid Spencer mkdir "$outdir" || exit 1 90024409995684ed37250a0d6dec4956316368a42aReid Spencerfi 9128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 9228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# Generate the disassembly 9328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerllvm-dis "$bcfile" -o "$ll" -f || exit 1 9428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 952232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencer# Generate the non-optimized program and its output 9628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerllc "$bcfile" -o "$s" -f || exit 1 97f8463a38bf04b822d009e9e4eaae2e4a3c930da4Reid Spencergcc "$s" -o "$prog" $ldflags || exit 1 982232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencer"$prog" $args > "$out" 2>&1 <$input 992232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencerex1=$? 10028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 10128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer# Current set of switches is empty 10228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerfunction tryit { 10328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer switches_to_use="$1" 10428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer opt $switches_to_use "$bcfile" -o "$optbc" -f || exit 10528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer llvm-dis "$optbc" -o "$optll" -f || exit 10628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer llc "$optbc" -o "$opts" -f || exit 107f8463a38bf04b822d009e9e4eaae2e4a3c930da4Reid Spencer gcc "$opts" -o "$optprog" $ldflags || exit 1082232a80ef13537c2ea840e4d877655b6e1ca8f62Reid Spencer "$optprog" $args > "$optout" 2>&1 <"$input" 10928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer ex2=$? 11028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 11128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer if [ -n "$match" ] ; then 11228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer if [ "$ex1" -ne "$ex2" ] ; then 11328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Return code not the same with these switches:" 11428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo $switches 11528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Unoptimized returned: $ex1" 11628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Optimized returned: $ex2" 11728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer return 0 11828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer fi 11928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer else 12028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer diff "$out" "$optout" > /dev/null 12128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer if [ $? -ne 0 ] ; then 12228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Diff fails with these switches:" 12328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo $switches 12428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Differences:" 125ba07a6922289d65690ce5f39301cd7e75c97d89eReid Spencer diff "$out" "$optout" | head 12628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer return 0; 12728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer fi 12828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer fi 12928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer return 1 13028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer} 13128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 132024409995684ed37250a0d6dec4956316368a42aReid Spencerecho "Trying to find optimization that breaks program:" 13328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerfor sw in $all_switches ; do 134024409995684ed37250a0d6dec4956316368a42aReid Spencer echo -n " $sw" 13528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer switches="$switches $sw" 13628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer if tryit "$switches" ; then 13728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer break; 13828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer fi 13928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerdone 14028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 1416d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencer# Terminate the previous output with a newline 1426d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencerecho "" 1436d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencer 1446d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencer# Determine if we're done because none of the optimizations broke the program 1456d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencerif [ "$switches" == " $all_switches" ] ; then 1466d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencer echo "The program did not miscompile" 1476d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencer exit 0 1486d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencerfi 1496d0fbd4185ae24f342459b1ed4ab45062bff1a66Reid Spencer 15028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerfinal="" 15128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerwhile [ ! -z "$switches" ] ; do 15228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer trimmed=`echo "$switches" | sed -e 's/^ *\(-[^ ]*\).*/\1/'` 15328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer switches=`echo "$switches" | sed -e 's/^ *-[^ ]* *//'` 15428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Trimmed $trimmed from left" 15528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer tryit "$final $switches" 15628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer if [ "$?" -eq "0" ] ; then 15728b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Still Failing .. continuing ..." 15828b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer continue 15928b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer else 16028b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Found required early pass: $trimmed" 16128b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer final="$final $trimmed" 16228b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer continue 16328b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer fi 16428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer echo "Next Loop" 16528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerdone 16628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 167dd2b95534f866ec6f31df101624a715612c97ffaReid Spencerif [ "$final" == " $all_switches" ] ; then 168024409995684ed37250a0d6dec4956316368a42aReid Spencer echo "findmisopt: All optimizations pass. Perhaps this isn't a misopt?" 169dd2b95534f866ec6f31df101624a715612c97ffaReid Spencer exit 0 170dd2b95534f866ec6f31df101624a715612c97ffaReid Spencerfi 171dd2b95534f866ec6f31df101624a715612c97ffaReid Spencerecho "Smallest Optimization list=$final" 172a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencer 173a8c3ff456aedbc55ac5ccd853e721812d0369ea0Reid Spencerbpcmd="$bugpoint -run-llc -disable-loop-extraction --output "$out" --input /dev/null $bcfile $final --args $args" 17428b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer 17528b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencerecho "Running: $bpcmd" 17628b7c7feab6219f4c9c7efc3b71a0a3f4880a14dReid Spencer$bpcmd 177dd2b95534f866ec6f31df101624a715612c97ffaReid Spencerecho "findmisopt finished." 178