Mikael Holmén via llvm-dev
2015-Aug-10 06:30 UTC
[llvm-dev] load instruction erroneously removed by GVN
Hi, On 08/07/2015 10:30 PM, Nick Lewycky wrote: [...]> Depends. What is the exact declaration of format_long? > > > In the input .ll file it is: > > ; Function Attrs: minsize optsize > define internal i16 @format_long(i16* %res.8.par, i16 %base.9.par, > i32 %x.10.par) #3 { > > which is later changed somewhere in opt to: > > ; Function Attrs: minsize nounwind optsize > define internal fastcc i16 @format_long(i16* %res.8.par, i16 > %base.9.par, i32 %x.10.par) #2 { > > > That's part of it, but we also need to see what #3 and #2 refer to in > this context. Those should be grouped at the end of your .ll, something like > > attributes #3 = { nobuiltin nounwind "less-precise-fpmad"="false" > "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" > "no-infs-fp-math"="false" "no-nans-fp-math"="false" > "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" > "use-soft-float"="false" }The attributes are attributes #3 = { minsize optsize "target-cpu"="phoenixIV" } and attributes #2 = { minsize nounwind optsize "target-cpu"="phoenixIV" } (I'm compiling for my out-of-tree target, thus the "target-cpu"="phoenixIV"). So no readonly or readnone attributes. Thanks, Mikael> > or > > attributes #2 = { nounwind readonly } > > If @format_long is marked with the 'readonly' or 'readnone' attribute > then GVN would be justified in doing the transformation you've described. > > Nick
Mikael Holmén via llvm-dev
2015-Aug-10 08:39 UTC
[llvm-dev] load instruction erroneously removed by GVN
Hi again, I've managed to reduce the code to make it easier to see what's going on. So my input to opt is: declare void @check(i8) declare void @write(i8* %res) define i8 @TEST1() { %buf = alloca [10 x i8] %_tmp30 = bitcast [10 x i8]* %buf to i8* call void @write(i8* %_tmp30) %_tmp33 = load i8, i8* %_tmp30 call void @check(i8 %_tmp33) ret i8 0 } and I run opt with build-all/bin/opt -S -memcpyopt -mldst-motion -gvn -O3 ./f2.ll and then the load is removed by GVN and %_tmp33 is replaced with undef. GVN iteration: 0 GVN removed: %_tmp33 = load i8, i8* %_tmp30 I notice that if I change TEST1 slightly, and rewrite it as define i8 @TEST2() { %buf = alloca i8 call void @write(i8* %buf) %_tmp33 = load i8, i8* %buf call void @check(i8 %_tmp33) ret i8 0 } then the load is left intact GVN iteration: 0 GVN: load i8 %_tmp33 is clobbered by call void @write(i8* %buf.17) In this case it seems to be the code if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true, /* StoreCaptures */ true, I, DT, /* include Object */ true, /* OrderedBasicBlock */ OBB)) return MRI_ModRef; in AliasAnalysis::callCapturesBefore that saves the load, which it doesn't in the first case. Anything obvious that I'm doing wrong or should I write a bug report on this? /Mikael On 08/10/2015 08:30 AM, Mikael Holmén via llvm-dev wrote:> Hi, > > On 08/07/2015 10:30 PM, Nick Lewycky wrote: > [...] > >> Depends. What is the exact declaration of format_long? >> >> >> In the input .ll file it is: >> >> ; Function Attrs: minsize optsize >> define internal i16 @format_long(i16* %res.8.par, i16 %base.9.par, >> i32 %x.10.par) #3 { >> >> which is later changed somewhere in opt to: >> >> ; Function Attrs: minsize nounwind optsize >> define internal fastcc i16 @format_long(i16* %res.8.par, i16 >> %base.9.par, i32 %x.10.par) #2 { >> >> >> That's part of it, but we also need to see what #3 and #2 refer to in >> this context. Those should be grouped at the end of your .ll, >> something like >> >> attributes #3 = { nobuiltin nounwind "less-precise-fpmad"="false" >> "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" >> "no-infs-fp-math"="false" "no-nans-fp-math"="false" >> "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" >> "use-soft-float"="false" } > > The attributes are > > attributes #3 = { minsize optsize "target-cpu"="phoenixIV" } > > and > > attributes #2 = { minsize nounwind optsize "target-cpu"="phoenixIV" } > > (I'm compiling for my out-of-tree target, thus the > "target-cpu"="phoenixIV"). > > So no readonly or readnone attributes. > > Thanks, > Mikael > >> >> or >> >> attributes #2 = { nounwind readonly } >> >> If @format_long is marked with the 'readonly' or 'readnone' attribute >> then GVN would be justified in doing the transformation you've described. >> >> Nick > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org http://llvm.cs.uiuc.edu > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Mikael Holmén via llvm-dev
2015-Aug-11 11:08 UTC
[llvm-dev] load instruction erroneously removed by GVN
I filed a TR for this problem: https://llvm.org/bugs/show_bug.cgi?id=24426 /Mikael On 08/10/2015 10:39 AM, Mikael Holmén via llvm-dev wrote:> Hi again, > > I've managed to reduce the code to make it easier to see what's going on. > > So my input to opt is: > > declare void @check(i8) > > declare void @write(i8* %res) > > define i8 @TEST1() { > %buf = alloca [10 x i8] > %_tmp30 = bitcast [10 x i8]* %buf to i8* > > call void @write(i8* %_tmp30) > > %_tmp33 = load i8, i8* %_tmp30 > call void @check(i8 %_tmp33) > > ret i8 0 > } > > and I run opt with > build-all/bin/opt -S -memcpyopt -mldst-motion -gvn -O3 ./f2.ll > > and then the load is removed by GVN and %_tmp33 is replaced with undef. > > GVN iteration: 0 > GVN removed: %_tmp33 = load i8, i8* %_tmp30 > > > I notice that if I change TEST1 slightly, and rewrite it as > > define i8 @TEST2() { > %buf = alloca i8 > > call void @write(i8* %buf) > > %_tmp33 = load i8, i8* %buf > call void @check(i8 %_tmp33) > > ret i8 0 > } > > then the load is left intact > > GVN iteration: 0 > GVN: load i8 %_tmp33 is clobbered by call void @write(i8* %buf.17) > > In this case it seems to be the code > > if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true, > /* StoreCaptures */ true, I, DT, > /* include Object */ true, > /* OrderedBasicBlock */ OBB)) > return MRI_ModRef; > > in AliasAnalysis::callCapturesBefore that saves the load, which it > doesn't in the first case. > > Anything obvious that I'm doing wrong or should I write a bug report on > this? > /Mikael > > > On 08/10/2015 08:30 AM, Mikael Holmén via llvm-dev wrote: >> Hi, >> >> On 08/07/2015 10:30 PM, Nick Lewycky wrote: >> [...] >> >>> Depends. What is the exact declaration of format_long? >>> >>> >>> In the input .ll file it is: >>> >>> ; Function Attrs: minsize optsize >>> define internal i16 @format_long(i16* %res.8.par, i16 %base.9.par, >>> i32 %x.10.par) #3 { >>> >>> which is later changed somewhere in opt to: >>> >>> ; Function Attrs: minsize nounwind optsize >>> define internal fastcc i16 @format_long(i16* %res.8.par, i16 >>> %base.9.par, i32 %x.10.par) #2 { >>> >>> >>> That's part of it, but we also need to see what #3 and #2 refer to in >>> this context. Those should be grouped at the end of your .ll, >>> something like >>> >>> attributes #3 = { nobuiltin nounwind "less-precise-fpmad"="false" >>> "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" >>> "no-infs-fp-math"="false" "no-nans-fp-math"="false" >>> "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" >>> "use-soft-float"="false" } >> >> The attributes are >> >> attributes #3 = { minsize optsize "target-cpu"="phoenixIV" } >> >> and >> >> attributes #2 = { minsize nounwind optsize "target-cpu"="phoenixIV" } >> >> (I'm compiling for my out-of-tree target, thus the >> "target-cpu"="phoenixIV"). >> >> So no readonly or readnone attributes. >> >> Thanks, >> Mikael >> >>> >>> or >>> >>> attributes #2 = { nounwind readonly } >>> >>> If @format_long is marked with the 'readonly' or 'readnone' attribute >>> then GVN would be justified in doing the transformation you've >>> described. >>> >>> Nick >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org http://llvm.cs.uiuc.edu >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org http://llvm.cs.uiuc.edu > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev