[LLVMdev] GVN fails with bitcasts

Nick Lewycky
Sat, 14 Dec 2013 08:14:15 -0000

Carl-Philip Hänsch wrote:
> Hi,
>
> i have the following code:
> define internal %"struct.dexter::ConditionConstant"*
>
@_ZN6dexter18BinaryConditionAdd8evaluateEv5(%"class.dexter::BinaryConditionAdd"*)
> {
> entry:
>    %1 = getelementptr inbounds
%"class.dexter::BinaryConditionAdd"* %0,
> i32 0, i32 0, i32 1
>    %2 = load %"class.dexter::BaseCondition"** %1, align 8
>    %3 = bitcast %"class.dexter::BaseCondition"* %2 to
> %"class.dexter::BinaryConditionAdd"*
>    %4 = getelementptr inbounds
%"class.dexter::BinaryConditionAdd"* %3,
> i32 0, i32 0, i32 0, i32 1, i32 0
>    %5 = bitcast %union.anon* %4 to i64*
>    store i64 4, i64* %5, align 8
>    %6 = getelementptr inbounds
%"class.dexter::BinaryConditionAdd"* %3,
> i32 0, i32 0, i32 0, i32 1
>    %7 = bitcast %"struct.dexter::ConditionConstant"* %6 to i64*
>    %8 = load i64* %7, align 8
>    %9 = add nsw i64 %8, 2
>    %10 = getelementptr inbounds
%"class.dexter::BinaryConditionAdd"* %0,
> i32 0, i32 0, i32 0, i32 1, i32 0
>    %11 = bitcast %union.anon* %10 to i64*
>    store i64 %9, i64* %11, align 8
>    %12 = getelementptr inbounds
%"class.dexter::BinaryConditionAdd"* %0,
> i32 0, i32 0, i32 0, i32 1
>    ret %"struct.dexter::ConditionConstant"* %12
> }
>
> %5 and %7 point to the same memory location. This is not detected
> because %4 and %6 look different. But they have the same offset and the
> bitcast creates. Do you have an idea how to fix that?

Without seeing the definition of class.dexter::BinaryConditionAdd it's
hard to tell. Is the element it's pointing to actually an i64? If it is,
then we could canonicalize the gep+bitcast to just a gep. If not, then
we need to have a GEP+bitcast situation, but it's possible that when we
see a GEP with a single use bitcast, we could canonicalize by stripping
trailing zeroes off the GEP?

If instcombine did that, would GVN then be able to solve this?

Nick