diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1551,6 +1551,16 @@ if (GV != GV2) { if (CE1GEP->hasAllZeroIndices()) return areGlobalsPotentiallyEqual(GV, GV2); + + const DataLayout &DL = GV->getParent()->getDataLayout(); + TypeSize ValueSize = + GV->getParent()->getDataLayout().getTypeAllocSize( + GV->getValueType()); + APInt Offset(DL.getIndexTypeSizeInBits(CE1GEP->getType()), 0); + if (CE1GEP->accumulateConstantOffset(DL, Offset) && + Offset.isNonNegative() && Offset.ult(ValueSize)) + return areGlobalsPotentiallyEqual(GV, GV2); + return ICmpInst::BAD_ICMP_PREDICATE; } } diff --git a/llvm/test/Other/constant-fold-gep.ll b/llvm/test/Other/constant-fold-gep.ll --- a/llvm/test/Other/constant-fold-gep.ll +++ b/llvm/test/Other/constant-fold-gep.ll @@ -470,6 +470,7 @@ @gv1 = internal global i32 1 @gv2 = internal global [1 x i32] [ i32 2 ] @gv3 = internal global [1 x i32] [ i32 2 ] +@gv4 = internal global [2 x i32] [ i32 2, i32 2 ] ; Handled by TI-independent constant folder define i1 @gv_gep_vs_gv() { @@ -478,6 +479,12 @@ ; PLAIN: gv_gep_vs_gv ; PLAIN: ret i1 false +define i1 @gv_gep_vs_gv_non_zero() { + ret i1 icmp eq (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @gv4, i32 0, i32 1), i32* @gv1) +} +; PLAIN: gv_gep_vs_gv_non_zero +; PLAIN: ret i1 false + define i1 @gv_gep_vs_gv_gep() { ret i1 icmp eq (i32* getelementptr inbounds ([1 x i32], [1 x i32]* @gv2, i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* @gv3, i32 0, i32 0)) } diff --git a/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll b/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll --- a/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll +++ b/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll @@ -96,7 +96,7 @@ ; CHECK-LABEL: @constantexpr2( ; CHECK-NEXT: [[I2:%.*]] = load i16*, i16** @global_constant5, align 1 ; CHECK-NEXT: [[I3:%.*]] = load i16, i16* [[I2]], align 1 -; CHECK-NEXT: [[I5:%.*]] = xor i16 [[I3]], xor (i16 zext (i1 icmp ne (i64* getelementptr inbounds ([6 x [1 x i64]], [6 x [1 x i64]]* @global_constant3, i64 0, i64 5, i64 0), i64* @global_constant4) to i16), i16 -1) +; CHECK-NEXT: [[I5:%.*]] = xor i16 [[I3]], -2 ; CHECK-NEXT: ret i16 [[I5]] ; %i0 = icmp ne i64* getelementptr inbounds ([6 x [1 x i64]], [6 x [1 x i64]]* @global_constant3, i16 0, i16 5, i16 0), @global_constant4