Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1445,6 +1445,10 @@ bool Swapped = false; GEPOperator *GEP1 = nullptr, *GEP2 = nullptr; + // This is primarially to deal with leading noalias intrinsics. + LHS = LHS->stripPointerCasts(/*LookThroughNoAlias*/true); + RHS = RHS->stripPointerCasts(/*LookThroughNoAlias*/true); + // For now we require one side to be the base pointer "A" or a constant // GEP derived from it. if (GEPOperator *LHSGEP = dyn_cast(LHS)) { @@ -1454,8 +1458,8 @@ Swapped = false; } else if (GEPOperator *RHSGEP = dyn_cast(RHS)) { // (gep X, ...) - (gep X, ...) - if (LHSGEP->getOperand(0)->stripPointerCasts() == - RHSGEP->getOperand(0)->stripPointerCasts()) { + if (LHSGEP->getOperand(0)->stripPointerCasts(true) == + RHSGEP->getOperand(0)->stripPointerCasts(true)) { GEP2 = RHSGEP; GEP1 = LHSGEP; Swapped = false; @@ -1470,8 +1474,8 @@ Swapped = true; } else if (GEPOperator *LHSGEP = dyn_cast(LHS)) { // (gep X, ...) - (gep X, ...) - if (RHSGEP->getOperand(0)->stripPointerCasts() == - LHSGEP->getOperand(0)->stripPointerCasts()) { + if (RHSGEP->getOperand(0)->stripPointerCasts(true) == + LHSGEP->getOperand(0)->stripPointerCasts(true)) { GEP2 = LHSGEP; GEP1 = RHSGEP; Swapped = true; Index: test/Transforms/InstCombine/sub.ll =================================================================== --- test/Transforms/InstCombine/sub.ll +++ test/Transforms/InstCombine/sub.ll @@ -308,6 +308,18 @@ ; CHECK-NEXT: ret i64 } +define i64 @test25a(i8* %P, i64 %A){ + %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A + %BA = call i16* @llvm.noalias.p0i16(i16* %B, metadata !1) + %C = ptrtoint i16* %BA to i64 + %G = sub i64 %C, ptrtoint (i16* getelementptr ([42 x i16], [42 x i16]* @Arr, i64 1, i64 0) to i64) + ret i64 %G +; CHECK-LABEL: @test25a( +; CHECK-NEXT: shl nuw i64 %A, 1 +; CHECK-NEXT: add i64 {{.*}}, -84 +; CHECK-NEXT: ret i64 +} + @Arr_as1 = external addrspace(1) global [42 x i16] define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) { @@ -550,3 +562,9 @@ ; CHECK-NEXT: %sub = and i32 %y, %x.not ; CHECK: ret i32 %sub } + +declare i16* @llvm.noalias.p0i16(i16*, metadata) nounwind + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} +