Stephan Plöger via llvm-dev
2016-Dec-19 16:41 UTC
[llvm-dev] opt -instcombine interesting behavior
Hi all, I've been playing around with the llvm optimizer and stumbled upon an interesting behavior with respect to the "instcombine" option. I tried to optimize the following small program (see also attachment small.ll) (only with "instcombine"): clang -v clang version 4.0.0 (trunk 288238) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/local/bin Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.4.0 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6.0.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Candidate multilib: x32;@mx32 Selected multilib: .;@m64 llvm-as small.ll -o small.bc opt -instcombine small.bc -o smallOpt.bc define i32 @main() { %reg = alloca i32, i32 0 store i32 1, i32* %reg %1 = getelementptr i32, i32* %reg, i32 0 %2 = bitcast i32* %1 to [4 x i8]* %3 = getelementptr [4 x i8], [4 x i8]* %2, i32 0, i32 1 store i8 1, i8* %3 %4 = load i32, i32* %reg ret i32 %4 } The program in pseudo code would/should simplified look something like this: int main(){ reg = 1; [reg+1] = 1; //Second byte of reg is set to 1 return reg; } I assumed it would be optimized to - again pseudo code -: int main(){ return 257; } Instead, the program is optimized to(see also attachment smallOpt.ll/smallOpt.bc): define i32 @main() { ret i32 1 } So i verified my assumption by printing '%4' of the original program (smallPrint.ll/smallPrint.bc) and the output was 257. I also optimized smallPrint.ll/smallPrint.bc , again only with instcombine, but the output is changed to 1 (smallPrintOpt.bc). I also tested it with clang 3.8.0. What am i missing? Best regards, Stephan -------------- next part -------------- A non-text attachment was scrubbed... Name: smallPrintOpt.bc Type: application/octet-stream Size: 868 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161219/421fcb23/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: smallPrint.bc Type: application/octet-stream Size: 912 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161219/421fcb23/attachment-0001.obj> -------------- next part -------------- @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00" declare i32 @printf(i8*, ...) #1 define i32 @main() { %reg = alloca i32, i32 0 store i32 1, i32* %reg %1 = getelementptr i32, i32* %reg, i32 0 %2 = bitcast i32* %1 to [4 x i8]* %3 = getelementptr [4 x i8], [4 x i8]* %2, i32 0, i32 1 store i8 1, i8* %3 %4 = load i32, i32* %reg %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %4) ret i32 %4 } -------------- next part -------------- ; ModuleID = 'smallOpt.bc' source_filename = "small.ll" define i32 @main() { ret i32 1 } -------------- next part -------------- A non-text attachment was scrubbed... Name: smallOpt.bc Type: application/octet-stream Size: 736 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161219/421fcb23/attachment-0002.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: small.bc Type: application/octet-stream Size: 796 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161219/421fcb23/attachment-0003.obj> -------------- next part -------------- define i32 @main() { %reg = alloca i32, i32 0 store i32 1, i32* %reg %1 = getelementptr i32, i32* %reg, i32 0 %2 = bitcast i32* %1 to [4 x i8]* %3 = getelementptr [4 x i8], [4 x i8]* %2, i32 0, i32 1 store i8 1, i8* %3 %4 = load i32, i32* %reg ret i32 %4 }
Tim Northover via llvm-dev
2016-Dec-19 17:13 UTC
[llvm-dev] opt -instcombine interesting behavior
Hi Stephan, On 19 December 2016 at 08:41, Stephan Plöger via llvm-dev <llvm-dev at lists.llvm.org> wrote:> %reg = alloca i32, i32 0This line is allocating 0 bytes rather than allocating an i32 and setting the memory to 0, so the rest of the function is really dodgy. I'm not sure exactly why InstCombine decides on 1, but really anything could have happened. Cheers. Tim.
Nema, Ashutosh via llvm-dev
2016-Dec-19 17:51 UTC
[llvm-dev] opt -instcombine interesting behavior
> %reg = alloca i32, i32 0Allocating 0 bytes is legal but it's an undefined behavior, please refer: http://llvm.org/docs/LangRef.html#id184 You need to correct allocation to get the desired output, i.e.:> %reg = alloca i32, i32 1Regards, Ashutosh> -----Original Message----- > From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of > Stephan Plöger via llvm-dev > Sent: Monday, December 19, 2016 10:11 PM > To: llvm-dev at lists.llvm.org > Subject: [llvm-dev] opt -instcombine interesting behavior > > Hi all, > > I've been playing around with the llvm optimizer and stumbled upon an > interesting behavior with respect to the "instcombine" option. I tried to > optimize the following small program (see also attachment small.ll) (only > with "instcombine"): > > clang -v > clang version 4.0.0 (trunk 288238) > Target: x86_64-unknown-linux-gnu > Thread model: posix > InstalledDir: /usr/local/bin > Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5 Found > candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.4.0 Found > candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6 Found candidate > GCC installation: /usr/lib/gcc/i686-linux-gnu/6.0.0 Found candidate GCC > installation: /usr/lib/gcc/x86_64-linux-gnu/5 Found candidate GCC > installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6 Found > candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0 > Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 > Candidate multilib: .;@m64 > Candidate multilib: 32;@m32 > Candidate multilib: x32;@mx32 > Selected multilib: .;@m64 > > > llvm-as small.ll -o small.bc > opt -instcombine small.bc -o smallOpt.bc > > > define i32 @main() { > %reg = alloca i32, i32 0 > store i32 1, i32* %reg > %1 = getelementptr i32, i32* %reg, i32 0 > %2 = bitcast i32* %1 to [4 x i8]* > %3 = getelementptr [4 x i8], [4 x i8]* %2, i32 0, i32 1 > store i8 1, i8* %3 > %4 = load i32, i32* %reg > ret i32 %4 > } > > The program in pseudo code would/should simplified look something like > this: > > int main(){ > reg = 1; > [reg+1] = 1; //Second byte of reg is set to 1 > return reg; > } > > I assumed it would be optimized to - again pseudo code -: > > int main(){ > return 257; > } > > Instead, the program is optimized to(see also attachment > smallOpt.ll/smallOpt.bc): > > define i32 @main() { > ret i32 1 > } > > So i verified my assumption by printing '%4' of the original program > (smallPrint.ll/smallPrint.bc) and the output was 257. > I also optimized smallPrint.ll/smallPrint.bc , again only with instcombine, but > the output is changed to 1 (smallPrintOpt.bc). > > I also tested it with clang 3.8.0. > > What am i missing? > > > Best regards, > Stephan
Mehdi Amini via llvm-dev
2016-Dec-19 18:01 UTC
[llvm-dev] opt -instcombine interesting behavior
> On Dec 19, 2016, at 9:51 AM, Nema, Ashutosh via llvm-dev <llvm-dev at lists.llvm.org> wrote: > >> %reg = alloca i32, i32 0 > Allocating 0 bytes is legal but it's an undefined behavior, please refer: > http://llvm.org/docs/LangRef.html#id184 <http://llvm.org/docs/LangRef.html#id184>Nit: I believe that when LangRef says “the result is undefined”, it does not mean “undefined behavior”. See http://llvm.org/docs/LangRef.html#undefined-values <http://llvm.org/docs/LangRef.html#undefined-values> for more details.> > You need to correct allocation to get the desired output, i.e.: >> %reg = alloca i32, i32 1The “, i32 1” is optional though (default is 1). — Mehdi> > Regards, > Ashutosh > >> -----Original Message----- >> From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of >> Stephan Plöger via llvm-dev >> Sent: Monday, December 19, 2016 10:11 PM >> To: llvm-dev at lists.llvm.org >> Subject: [llvm-dev] opt -instcombine interesting behavior >> >> Hi all, >> >> I've been playing around with the llvm optimizer and stumbled upon an >> interesting behavior with respect to the "instcombine" option. I tried to >> optimize the following small program (see also attachment small.ll) (only >> with "instcombine"): >> >> clang -v >> clang version 4.0.0 (trunk 288238) >> Target: x86_64-unknown-linux-gnu >> Thread model: posix >> InstalledDir: /usr/local/bin >> Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5 Found >> candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.4.0 Found >> candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6 Found candidate >> GCC installation: /usr/lib/gcc/i686-linux-gnu/6.0.0 Found candidate GCC >> installation: /usr/lib/gcc/x86_64-linux-gnu/5 Found candidate GCC >> installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 >> Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6 Found >> candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0 >> Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 >> Candidate multilib: .;@m64 >> Candidate multilib: 32;@m32 >> Candidate multilib: x32;@mx32 >> Selected multilib: .;@m64 >> >> >> llvm-as small.ll -o small.bc >> opt -instcombine small.bc -o smallOpt.bc >> >> >> define i32 @main() { >> %reg = alloca i32, i32 0 >> store i32 1, i32* %reg >> %1 = getelementptr i32, i32* %reg, i32 0 >> %2 = bitcast i32* %1 to [4 x i8]* >> %3 = getelementptr [4 x i8], [4 x i8]* %2, i32 0, i32 1 >> store i8 1, i8* %3 >> %4 = load i32, i32* %reg >> ret i32 %4 >> } >> >> The program in pseudo code would/should simplified look something like >> this: >> >> int main(){ >> reg = 1; >> [reg+1] = 1; //Second byte of reg is set to 1 >> return reg; >> } >> >> I assumed it would be optimized to - again pseudo code -: >> >> int main(){ >> return 257; >> } >> >> Instead, the program is optimized to(see also attachment >> smallOpt.ll/smallOpt.bc): >> >> define i32 @main() { >> ret i32 1 >> } >> >> So i verified my assumption by printing '%4' of the original program >> (smallPrint.ll/smallPrint.bc) and the output was 257. >> I also optimized smallPrint.ll/smallPrint.bc , again only with instcombine, but >> the output is changed to 1 (smallPrintOpt.bc). >> >> I also tested it with clang 3.8.0. >> >> What am i missing? >> >> >> Best regards, >> Stephan > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161219/f0b5cfe5/attachment.html>
Maybe Matching Threads
- opt -instcombine interesting behavior
- opt -instcombine interesting behavior
- Instcombine and bitcast of vector. Wrong CHECKs in cast.ll, miscompile in instcombine?
- [LLVMdev] -instcombine introduces "undef" values to the IR.
- [LLVMdev] InstCombine "pessimizes" trunc i8 to i1?