Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -2635,11 +2635,29 @@ Opts.NullIsUnknownSize = NullPointerIsDefined(cast<AllocaInst>(LHS)->getFunction()); if (getObjectSize(LHS, LHSSize, DL, TLI, Opts) && - getObjectSize(RHS, RHSSize, DL, TLI, Opts) && - !LHSOffset.isNegative() && !RHSOffset.isNegative() && - LHSOffset.ult(LHSSize) && RHSOffset.ult(RHSSize)) { - return ConstantInt::get(GetCompareTy(LHS), - !CmpInst::isTrueWhenEqual(Pred)); + getObjectSize(RHS, RHSSize, DL, TLI, Opts)) { + auto CanNotOverlap = [&]() -> bool { + if (!LHSOffset.isNegative() && !RHSOffset.isNegative()) { + return ((LHSOffset.ult(LHSSize) || + (LHSOffset - LHSSize).ult(RHSOffset)) && + (RHSOffset.ult(RHSSize) || + (RHSOffset - RHSSize).ult(LHSOffset))); + } + auto LAbs = LHSOffset.sext(LHSOffset.getBitWidth() + 1).abs(); + auto RAbs = RHSOffset.sext(RHSOffset.getBitWidth() + 1).abs(); + if (LHSOffset.isNegative() && RHSOffset.isNegative()) + // TODO: Add corresponding max offset in other case (inverse + // of the positive version) + return (LAbs.ult(RHSSize) && RAbs.ult(LHSSize)); + if (!LHSOffset.isNegative() && RHSOffset.isNegative()) + return (LAbs + RAbs).ult(LHSSize); + if (LHSOffset.isNegative() && !RHSOffset.isNegative()) + return (LAbs + RAbs).ult(RHSSize); + llvm_unreachable(""); + }; + if (CanNotOverlap()) + return ConstantInt::get(GetCompareTy(LHS), + !CmpInst::isTrueWhenEqual(Pred)); } } Index: llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll =================================================================== --- llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll +++ llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll @@ -42,15 +42,10 @@ ret i1 %res } -; FIXME: Can't be equal +; Can't be equal define i1 @positive_non_equal_end() { ; CHECK-LABEL: @positive_non_equal_end( -; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 4 -; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 4 -; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %a = alloca i8, i32 4 %b = alloca i8, i32 4 @@ -144,15 +139,10 @@ ret i1 %res } -; FIXME: Can't be equal +; Can't be equal define i1 @mixed_offsets1() { ; CHECK-LABEL: @mixed_offsets1( -; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 -1 -; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 2 -; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %a = alloca i8, i32 4 %b = alloca i8, i32 4 @@ -162,15 +152,10 @@ ret i1 %res } -; FIXME: Can't be equal +; Can't be equal define i1 @mixed_offsets2() { ; CHECK-LABEL: @mixed_offsets2( -; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 1 -; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 -2 -; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %a = alloca i8, i32 4 %b = alloca i8, i32 4 @@ -180,15 +165,10 @@ ret i1 %res } -; FIXME: Can't be equal +; Can't be equal define i1 @negative_in_other() { ; CHECK-LABEL: @negative_in_other( -; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 -; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 -3 -; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 -2 -; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %a = alloca i8, i32 4 %b = alloca i8, i32 4 Index: llvm/test/Transforms/InstSimplify/past-the-end.ll =================================================================== --- llvm/test/Transforms/InstSimplify/past-the-end.ll +++ llvm/test/Transforms/InstSimplify/past-the-end.ll @@ -58,12 +58,7 @@ define zeroext i1 @both_past_the_end_alloca() { ; CHECK-LABEL: @both_past_the_end_alloca( -; CHECK: [[M:%.*]] = alloca i32 -; CHECK-NEXT: [[N:%.*]] = alloca i32 -; CHECK-NEXT: [[X:%.*]] = getelementptr i32, i32* [[M]], i32 1 -; CHECK-NEXT: [[Y:%.*]] = getelementptr i32, i32* [[N]], i32 1 -; CHECK-NEXT: [[T:%.*]] = icmp eq i32* [[X]], [[Y]] -; CHECK-NEXT: ret i1 [[T]] +; CHECK-NEXT: ret i1 false ; %m = alloca i32 %n = alloca i32