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