[llvm-dev] load instruction erroneously removed by GVN
Mikael Holmén via llvm-dev
llvm-dev at lists.llvm.org
Mon Aug 10 01:39:56 PDT 2015
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
More information about the llvm-dev
mailing list