xref: /aosp_15_r20/external/llvm/utils/findmisopt (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker#!/bin/bash
2*9880d681SAndroid Build Coastguard Worker#
3*9880d681SAndroid Build Coastguard Worker#  findmisopt
4*9880d681SAndroid Build Coastguard Worker#
5*9880d681SAndroid Build Coastguard Worker#      This is a quick and dirty hack to potentially find a misoptimization
6*9880d681SAndroid Build Coastguard Worker#      problem. Mostly its to work around problems in bugpoint that prevent
7*9880d681SAndroid Build Coastguard Worker#      it from finding a problem unless the set of failing optimizations are
8*9880d681SAndroid Build Coastguard Worker#      known and given to it on the command line.
9*9880d681SAndroid Build Coastguard Worker#
10*9880d681SAndroid Build Coastguard Worker#      Given a bitcode file that produces correct output (or return code),
11*9880d681SAndroid Build Coastguard Worker#      this script will run through all the optimizations passes that gccas
12*9880d681SAndroid Build Coastguard Worker#      uses (in the same order) and will narrow down which optimizations
13*9880d681SAndroid Build Coastguard Worker#      cause the program either generate different output or return a
14*9880d681SAndroid Build Coastguard Worker#      different result code. When the passes have been narrowed down,
15*9880d681SAndroid Build Coastguard Worker#      bugpoint is invoked to further refine the problem to its origin. If a
16*9880d681SAndroid Build Coastguard Worker#      release version of bugpoint is available it will be used, otherwise
17*9880d681SAndroid Build Coastguard Worker#      debug.
18*9880d681SAndroid Build Coastguard Worker#
19*9880d681SAndroid Build Coastguard Worker#   Usage:
20*9880d681SAndroid Build Coastguard Worker#      findmisopt bcfile outdir progargs [match]
21*9880d681SAndroid Build Coastguard Worker#
22*9880d681SAndroid Build Coastguard Worker#   Where:
23*9880d681SAndroid Build Coastguard Worker#      bcfile
24*9880d681SAndroid Build Coastguard Worker#          is the bitcode file input (the unoptimized working case)
25*9880d681SAndroid Build Coastguard Worker#      outdir
26*9880d681SAndroid Build Coastguard Worker#          is a directory into which intermediate results are placed
27*9880d681SAndroid Build Coastguard Worker#      progargs
28*9880d681SAndroid Build Coastguard Worker#          is a single argument containing all the arguments the program needs
29*9880d681SAndroid Build Coastguard Worker#      proginput
30*9880d681SAndroid Build Coastguard Worker#          is a file name from which stdin should be directed
31*9880d681SAndroid Build Coastguard Worker#      match
32*9880d681SAndroid Build Coastguard Worker#          if specified to any value causes the result code of the program to
33*9880d681SAndroid Build Coastguard Worker#          be used to determine success/fail. If not specified success/fail is
34*9880d681SAndroid Build Coastguard Worker#          determined by diffing the program's output with the non-optimized
35*9880d681SAndroid Build Coastguard Worker#          output.
36*9880d681SAndroid Build Coastguard Worker#
37*9880d681SAndroid Build Coastguard Workerif [ "$#" -lt 3 ] ; then
38*9880d681SAndroid Build Coastguard Worker  echo "usage: findmisopt bcfile outdir progargs [match]"
39*9880d681SAndroid Build Coastguard Worker  exit 1
40*9880d681SAndroid Build Coastguard Workerfi
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Workerdir="${0%%/utils/findmisopt}"
43*9880d681SAndroid Build Coastguard Workerif [ -x "$dir/Release/bin/bugpoint" ] ; then
44*9880d681SAndroid Build Coastguard Worker  bugpoint="$dir/Release/bin/bugpoint"
45*9880d681SAndroid Build Coastguard Workerelif [ -x "$dir/Debug/bin/bugpoint" ] ; then
46*9880d681SAndroid Build Coastguard Worker  bugpoint="$dir/Debug/bin/bugpoint"
47*9880d681SAndroid Build Coastguard Workerelse
48*9880d681SAndroid Build Coastguard Worker  echo "findmisopt: bugpoint not found"
49*9880d681SAndroid Build Coastguard Worker  exit 1
50*9880d681SAndroid Build Coastguard Workerfi
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerbcfile="$1"
53*9880d681SAndroid Build Coastguard Workeroutdir="$2"
54*9880d681SAndroid Build Coastguard Workerargs="$3"
55*9880d681SAndroid Build Coastguard Workerinput="$4"
56*9880d681SAndroid Build Coastguard Workerif [ ! -f "$input" ] ; then
57*9880d681SAndroid Build Coastguard Worker  input="/dev/null"
58*9880d681SAndroid Build Coastguard Workerfi
59*9880d681SAndroid Build Coastguard Workermatch="$5"
60*9880d681SAndroid Build Coastguard Workername=`basename $bcfile .bc`
61*9880d681SAndroid Build Coastguard Workerll="$outdir/${name}.ll"
62*9880d681SAndroid Build Coastguard Workers="$outdir/${name}.s"
63*9880d681SAndroid Build Coastguard Workerprog="$outdir/${name}"
64*9880d681SAndroid Build Coastguard Workerout="$outdir/${name}.out"
65*9880d681SAndroid Build Coastguard Workeroptbc="$outdir/${name}.opt.bc"
66*9880d681SAndroid Build Coastguard Workeroptll="$outdir/${name}.opt.ll"
67*9880d681SAndroid Build Coastguard Workeropts="$outdir/${name}.opt.s"
68*9880d681SAndroid Build Coastguard Workeroptprog="$outdir/${name}.opt"
69*9880d681SAndroid Build Coastguard Workeroptout="$outdir/${name}.opt.out"
70*9880d681SAndroid Build Coastguard Workerldflags="-lstdc++ -lm -ldl -lc"
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Workerecho "Test Name: $name"
73*9880d681SAndroid Build Coastguard Workerecho "Unoptimized program: $prog"
74*9880d681SAndroid Build Coastguard Workerecho "  Optimized program: $optprog"
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker# Define the list of optimizations to run. This comprises the same set of
77*9880d681SAndroid Build Coastguard Worker# optimizations that opt -O3 runs, in the same order.
78*9880d681SAndroid Build Coastguard Workeropt_switches=`llvm-as < /dev/null -o - | opt -O3 -disable-output -debug-pass=Arguments 2>&1 | sed 's/Pass Arguments: //'`
79*9880d681SAndroid Build Coastguard Workerall_switches="$opt_switches"
80*9880d681SAndroid Build Coastguard Workerecho "Passes : $all_switches"
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker# Create output directory if it doesn't exist
83*9880d681SAndroid Build Coastguard Workerif [ -f "$outdir" ] ; then
84*9880d681SAndroid Build Coastguard Worker  echo "$outdir is not a directory"
85*9880d681SAndroid Build Coastguard Worker  exit 1
86*9880d681SAndroid Build Coastguard Workerfi
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Workerif [ ! -d "$outdir" ] ; then
89*9880d681SAndroid Build Coastguard Worker  mkdir "$outdir" || exit 1
90*9880d681SAndroid Build Coastguard Workerfi
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker# Generate the disassembly
93*9880d681SAndroid Build Coastguard Workerllvm-dis "$bcfile" -o "$ll" -f || exit 1
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker# Generate the non-optimized program and its output
96*9880d681SAndroid Build Coastguard Workerllc "$bcfile" -o "$s" -f || exit 1
97*9880d681SAndroid Build Coastguard Workergcc "$s" -o "$prog" $ldflags || exit 1
98*9880d681SAndroid Build Coastguard Worker"$prog" $args > "$out" 2>&1 <$input
99*9880d681SAndroid Build Coastguard Workerex1=$?
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker# Current set of switches is empty
102*9880d681SAndroid Build Coastguard Workerfunction tryit {
103*9880d681SAndroid Build Coastguard Worker  switches_to_use="$1"
104*9880d681SAndroid Build Coastguard Worker  opt $switches_to_use "$bcfile" -o "$optbc" -f || exit
105*9880d681SAndroid Build Coastguard Worker  llvm-dis "$optbc" -o "$optll" -f || exit
106*9880d681SAndroid Build Coastguard Worker  llc "$optbc" -o "$opts" -f || exit
107*9880d681SAndroid Build Coastguard Worker  gcc "$opts" -o "$optprog" $ldflags || exit
108*9880d681SAndroid Build Coastguard Worker  "$optprog" $args > "$optout" 2>&1 <"$input"
109*9880d681SAndroid Build Coastguard Worker  ex2=$?
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker  if [ -n "$match" ] ; then
112*9880d681SAndroid Build Coastguard Worker    if [ "$ex1" -ne "$ex2" ] ; then
113*9880d681SAndroid Build Coastguard Worker      echo "Return code not the same with these switches:"
114*9880d681SAndroid Build Coastguard Worker      echo $switches
115*9880d681SAndroid Build Coastguard Worker      echo "Unoptimized returned: $ex1"
116*9880d681SAndroid Build Coastguard Worker      echo "Optimized   returned: $ex2"
117*9880d681SAndroid Build Coastguard Worker      return 0
118*9880d681SAndroid Build Coastguard Worker    fi
119*9880d681SAndroid Build Coastguard Worker  else
120*9880d681SAndroid Build Coastguard Worker    diff "$out" "$optout" > /dev/null
121*9880d681SAndroid Build Coastguard Worker    if [ $? -ne 0 ] ; then
122*9880d681SAndroid Build Coastguard Worker      echo "Diff fails with these switches:"
123*9880d681SAndroid Build Coastguard Worker      echo $switches
124*9880d681SAndroid Build Coastguard Worker      echo "Differences:"
125*9880d681SAndroid Build Coastguard Worker      diff "$out" "$optout" | head
126*9880d681SAndroid Build Coastguard Worker      return 0;
127*9880d681SAndroid Build Coastguard Worker    fi
128*9880d681SAndroid Build Coastguard Worker  fi
129*9880d681SAndroid Build Coastguard Worker  return 1
130*9880d681SAndroid Build Coastguard Worker}
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workerecho "Trying to find optimization that breaks program:"
133*9880d681SAndroid Build Coastguard Workerfor sw in $all_switches ; do
134*9880d681SAndroid Build Coastguard Worker  echo -n " $sw"
135*9880d681SAndroid Build Coastguard Worker  switches="$switches $sw"
136*9880d681SAndroid Build Coastguard Worker  if tryit "$switches" ; then
137*9880d681SAndroid Build Coastguard Worker    break;
138*9880d681SAndroid Build Coastguard Worker  fi
139*9880d681SAndroid Build Coastguard Workerdone
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker# Terminate the previous output with a newline
142*9880d681SAndroid Build Coastguard Workerecho ""
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker# Determine if we're done because none of the optimizations broke the program
145*9880d681SAndroid Build Coastguard Workerif [ "$switches" == " $all_switches" ] ; then
146*9880d681SAndroid Build Coastguard Worker  echo "The program did not miscompile"
147*9880d681SAndroid Build Coastguard Worker  exit 0
148*9880d681SAndroid Build Coastguard Workerfi
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Workerfinal=""
151*9880d681SAndroid Build Coastguard Workerwhile [ ! -z "$switches" ] ; do
152*9880d681SAndroid Build Coastguard Worker  trimmed=`echo "$switches" | sed -e 's/^ *\(-[^ ]*\).*/\1/'`
153*9880d681SAndroid Build Coastguard Worker  switches=`echo "$switches" | sed -e 's/^ *-[^ ]* *//'`
154*9880d681SAndroid Build Coastguard Worker  echo "Trimmed $trimmed from left"
155*9880d681SAndroid Build Coastguard Worker  tryit "$final $switches"
156*9880d681SAndroid Build Coastguard Worker  if [ "$?" -eq "0" ] ; then
157*9880d681SAndroid Build Coastguard Worker    echo "Still Failing .. continuing ..."
158*9880d681SAndroid Build Coastguard Worker    continue
159*9880d681SAndroid Build Coastguard Worker  else
160*9880d681SAndroid Build Coastguard Worker    echo "Found required early pass: $trimmed"
161*9880d681SAndroid Build Coastguard Worker    final="$final $trimmed"
162*9880d681SAndroid Build Coastguard Worker    continue
163*9880d681SAndroid Build Coastguard Worker  fi
164*9880d681SAndroid Build Coastguard Worker  echo "Next Loop"
165*9880d681SAndroid Build Coastguard Workerdone
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Workerif [ "$final" == " $all_switches" ] ; then
168*9880d681SAndroid Build Coastguard Worker  echo "findmisopt: All optimizations pass. Perhaps this isn't a misopt?"
169*9880d681SAndroid Build Coastguard Worker  exit 0
170*9880d681SAndroid Build Coastguard Workerfi
171*9880d681SAndroid Build Coastguard Workerecho "Smallest Optimization list=$final"
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Workerbpcmd="$bugpoint -run-llc -disable-loop-extraction --output "$out" --input /dev/null $bcfile $final --args $args"
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Workerecho "Running: $bpcmd"
176*9880d681SAndroid Build Coastguard Worker$bpcmd
177*9880d681SAndroid Build Coastguard Workerecho "findmisopt finished."
178