#!/usr/bin/perl -w use strict; my @O_strategies = qw( -O0 -O1 -O2 -O3 -Os -Ofast ); my @f_options = qw( -fdefault-inline -fdefer-pop -fforward-propagate -ffp-contract=off -ffp-contract=fast -ffp-contract=on -fomit-frame-pointer -foptimize-sibling-calls -finline -finline-small-functions -findirect-inlining -finline-functions -finline-functions-called-once -fearly-inlining -fipa-sra -finline-limit=n -fkeep-inline-functions -fkeep-static-consts -fmerge-constants -fmerge-all-constants -fmodulo-sched -fmodulo-sched-allow-regmoves -fbranch-count-reg -ffunction-cse -fzero-initialized-in-bss -fthread-jumps -fsplit-wide-types -fcse-follow-jumps -fcse-skip-blocks -frerun-cse-after-loop -fgcse -fgcse-lm -fgcse-sm -fgcse-las -fgcse-after-reload -funsafe-loop-optimizations -fcrossjumping -fauto-inc-dec -fdce -fdse -fif-conversion -fif-conversion2 -fdelete-null-pointer-checks -fdevirtualize -fexpensive-optimizations -foptimize-register-move -fregmove -fira-loop-pressure -fira-share-save-slots -fira-share-spill-slots -fschedule-insns2 -fsched-interblock -fsched-spec -fsched-pressure -fsched-spec-load -fsched-spec-load-dangerous -fsched-stalled-insns=n -fsched2-use-superblocks -fsched-group-heuristic -fsched-critical-path-heuristic -fsched-spec-insn-heuristic -fsched-rank-heuristic -fsched-last-insn-heuristic -fsched-dep-count-heuristic -freschedule-modulo-scheduled-loops -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops -fcaller-saves -fcombine-stack-adjustments -fconserve-stack -ftree-reassoc -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-copy-prop -fipa-pure-const -fipa-reference -fipa-pta -fipa-profile -fipa-cp -fipa-cp-clone -fipa-matrix-reorg -ftree-sink -ftree-bit-ccp -ftree-ccp -ftree-switch-conversion -ftree-dce -ftree-builtin-call-dce -ftree-dominator-opts -ftree-dse -ftree-ch -ftree-loop-optimize -fcheck-data-deps -ftree-loop-if-convert -ftree-loop-if-convert-stores -ftree-loop-distribution -ftree-loop-distribute-patterns -ftree-loop-im -ftree-loop-ivcanon -fivopts -ftree-parallelize-loops=n -ftree-pta -ftree-sra -ftree-copyrename -ftree-ter -ftree-vectorize -ftree-slp-vectorize -ftree-vect-loop-version -fvect-cost-model -ftree-vrp -ftracer -funroll-loops -funroll-all-loops -fsplit-ivs-in-unroller -fvariable-expansion-in-unroller -fpartial-inlining -fpredictive-commoning -fprefetch-loop-arrays -fpeephole -fpeephole2 -fguess-branch-probability -freorder-blocks -freorder-blocks-and-partition -freorder-functions -fstrict-overflow -falign-functions -falign-labels -falign-loops -falign-jumps -ftoplevel-reorder -fweb -fwhole-program -fcompare-elim -fcprop-registers -fprofile-generate -ffloat-store -fexcess-precision=fast -fexcess-precision=standard -ffast-math -fmath-errno -funsafe-math-optimizations -fassociative-math -freciprocal-math -ffinite-math-only -fsigned-zeros -ftrapping-math -frounding-math -fsignaling-nans -fsingle-precision-constant -fcx-limited-range -fcx-fortran-rules -fprofile-values -fvpt -frename-registers -fpeel-loops -fmove-loop-invariants -funswitch-loops -fbranch-target-load-optimize -fbranch-target-load-optimize2 -fbtr-bb-exclusive -fstack-protector -fsection-anchors -fmerge-debug-strings -fdwarf2-cfi-asm -fprofile-arcs -feliminate-unused-debug-types -mfp-ret-in-387 -mfancy-math-387 -malign-double -mstackrealign -mpreferred-stack-boundary=n -mcld -mvzeroupper -mcx16 -msahf -mmovbe -mcrc32 -mrecip -mpush-args -maccumulate-outgoing-args -malign-stringops -minline-all-stringops -minline-stringops-dynamically -momit-leaf-frame-pointer -msse2avx -mfentry -m8bit-idiv -mavx256-split-unaligned-load -mavx256-split-unaligned-store -mred-zone -fcommon -fstrict-volatile-bitfields ); my @other_options = qw( -g -ggdb -gstabs -gstabs+ -p -pg -masm=intel -ftrapv -fwrapv -fexceptions -fnon-call-exceptions -funwind-tables -fpcc-struct-return -freg-struct-return -fshort-enums -fshort-double -fshort-wchar -fno-jump-tables -fpack-struct=1 -fpack-struct=2 -fpack-struct=4 -fpack-struct=8 -finstrument-functions -fstack-check -fsplit-stack ); my @arch_options = ( "-mtune=generic", "-m32 -mtune=generic", "-march=native", "-m32 -march=native", "-march=native -mcmodel=small", "-march=native -mcmodel=kernel", "-march=native -mcmodel=medium", "-march=native -mcmodel=large", "-m32 -march=i386", "-m32 -march=i486", "-m32 -march=i586", "-m32 -march=i686", "-march=nocona", "-m32 -march=nocona", "-march=corei7", "-m32 -march=corei7", "-march=corei7-avx", "-m32 -march=corei7-avx", "-march=atom", "-m32 -march=atom", "-m32 -march=athlon", "-march=athlon64-sse3", "-m32 -march=athlon64-sse3", "-march=barcelona", "-m32 -march=barcelona", ); my @DELETE = ( qr/-fomit-frame-pointer.*-pg/, ## Incompatible qr/-pg.*-fomit-frame-pointer/, qr/-fsection-anchors.*-fno-toplevel-reorder/, ## Incompatible qr/-fno-toplevel-reorder.*-fsection-anchors/, qr/-m32.*-mno-push-args/, ## Bug 48722 qr/-mno-push-args.*-m32/, ); my @O_equivalents = ( "s/-O1/-O0 -fauto-inc-dec -fcompare-elim -fcprop-registers -fdce -fdefer-pop -fdelayed-branch -fdse -fguess-branch-probability -fif-conversion2 -fif-conversion -fipa-pure-const -fipa-profile -fipa-reference -fmerge-constants -fsplit-wide-types -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-sra -ftree-pta -ftree-ter -funit-at-a-time/" , "s/-O2/-O1 -fthread-jumps -falign-functions -falign-jumps -falign-loops -falign-labels -fcaller-saves -fcrossjumping -fcse-follow-jumps -fcse-skip-blocks -fdelete-null-pointer-checks -fdevirtualize -fexpensive-optimizations -fgcse -fgcse-lm -finline-small-functions -findirect-inlining -fipa-sra -foptimize-sibling-calls -fpartial-inlining -fpeephole2 -fregmove -freorder-blocks -freorder-functions -frerun-cse-after-loop -fsched-interblock -fsched-spec -fschedule-insns -fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-switch-conversion -ftree-pre -ftree-vrp/" , "s/-O3/-O2 -finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-vectorize -fipa-cp-clone/" , "s/-Os/-O1 -fthread-jumps -fcaller-saves -fcrossjumping -fcse-follow-jumps -fcse-skip-blocks -fdelete-null-pointer-checks -fdevirtualize -fexpensive-optimizations -fgcse -fgcse-lm -finline-small-functions -findirect-inlining -fipa-sra -foptimize-sibling-calls -fpartial-inlining -fpeephole2 -fregmove -freorder-functions -frerun-cse-after-loop -fsched-interblock -fsched-spec -fschedule-insns -fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-switch-conversion -ftree-pre -ftree-vrp/" , "s/-Ofast/-O3 -ffast-math/", ); my $CSmith = "../csmith-2.0.0/src/csmith"; my $GCC = "ajo-gcc -w -I../csmith-2.0.0/runtime"; my $force_cflags = "-fno-strict-aliasing -fno-tree-fre -c -o /dev/null"; sub compile { my $fname = shift @_; ## Get a random set of options. my $strategy = $O_strategies[rand @O_strategies]; my $arch = $arch_options[rand @arch_options]; my $cmd = "$GCC $arch $strategy"; my $num_fopts = 2 + int(rand(5)); for (my $i=0; $i < $num_fopts; ++$i) { my $opt = $f_options[rand @f_options]; if ($opt =~ /=n$/) { # It's a numeric option. $opt =~ s/n$//; $opt .= 4+int(rand(8)); } elsif ($opt =~ /=/) { # It's an enum option; do nothing. } else { # It's a boolean option. if (int(rand(2)) == 0) { $opt =~ s/^(..)/$1no-/; } } $cmd .= " $opt"; } my $num_oopts = 1 + int(rand(4)); for (my $i=0; $i < $num_oopts; ++$i) { $cmd .= " "; $cmd .= $other_options[rand @other_options]; } ## Remove DELETEd option pairs. foreach my $d (@DELETE) { return 0 if ($cmd =~ $d); } $cmd .= " $fname"; $cmd .= " $force_cflags"; ## print "Running:\n ${cmd}\n"; my $output = `ulimit -t 8 ; $cmd 2>&1`; my $bug = 0; my $orig_exit_code = $?; if ($? == -1) { print "Compiler failed to execute: $!\n"; } elsif ($? & 127) { printf "Compiler died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; $bug = 1; } elsif ($? >> 8) { printf "Compiler exited with value %d\n", $? >> 8; $bug = 1; } return 0 unless $bug; ## At this point we've found a bug! Try to reduce $cmd. print "UNREDUCED: $cmd\n"; if ($output =~ /internal compiler error: in spill_failure/) { print "Yet another register allocator spill_failure.\n"; return 1; } print $output; foreach my $r (@O_equivalents) { eval("\$cmd =~ $r"); } system("ulimit -t 8 ; $cmd 2>&1"); my $exit_code = $?; if ($exit_code == $orig_exit_code) { print "REDUCED: $cmd\n"; } return 1; } sub do_test { my $seed = shift @_; my $fname = "bug${seed}.c"; print "Seed $seed: generating \r"; system("$CSmith --bitfields --packed-struct -s ${seed} > $fname"); print "Seed $seed: compiling 1 \r"; my $bugs = compile($fname); print "Seed $seed: compiling 2 \r"; $bugs += compile($fname); print "Seed $seed: compiling 3 \r"; $bugs += compile($fname); if ($bugs == 0) { unlink $fname; } } my $seed = int(rand(2000000000)); for (my $i=0; $i < 100000; ++$i) { do_test(++$seed); }