Index: llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp +++ llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp @@ -1232,8 +1232,8 @@ } } else if (match(I, m_Sub(m_SExt(m_Value(LHS)), m_SExt(m_Value(RHS))))) { if (LHS->getType() == RHS->getType()) { - const SCEV *Key = - SE->getAddExpr(SE->getUnknown(LHS), SE->getUnknown(RHS)); + const SCEV *Key = SE->getAddExpr( + SE->getUnknown(LHS), SE->getNegativeSCEV(SE->getUnknown(RHS))); if (auto *Dom = findClosestMatchingDominator(Key, I, DominatingSubs)) { Instruction *NewSExt = new SExtInst(Dom, I->getType(), "", I); NewSExt->takeName(I); @@ -1253,8 +1253,8 @@ } } else if (match(I, m_NSWSub(m_Value(LHS), m_Value(RHS)))) { if (programUndefinedIfPoison(I)) { - const SCEV *Key = - SE->getAddExpr(SE->getUnknown(LHS), SE->getUnknown(RHS)); + const SCEV *Key = SE->getAddExpr( + SE->getUnknown(LHS), SE->getNegativeSCEV(SE->getUnknown(RHS))); DominatingSubs[Key].push_back(I); } } Index: llvm/test/Transforms/SeparateConstOffsetFromGEP/AArch64/split-gep-sub.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SeparateConstOffsetFromGEP/AArch64/split-gep-sub.ll @@ -0,0 +1,40 @@ +; RUN: llc --mtriple aarch64-unknown-linux -O3 -aarch64-enable-gep-opt \ +; RUN: -start-before=separate-const-offset-from-gep \ +; RUN: -print-after=separate-const-offset-from-gep < %s 2>&1 | FileCheck %s + +define void @test(ptr %p) { +entry: + %0 = tail call i32 @foo() + %rem = srem i32 %0, 5 + %add = add nsw i32 %rem , 511 + br label %for.body + +for.body: + %k = phi i32 [ 0, %entry ], [ %inc, %cond.end ] + %mul = mul nuw nsw i32 %k, 5 + %sub1 = sub nsw i32 %mul, %rem + %cmp26 = icmp ult i32 %sub1, 512 + br i1 %cmp26, label %cond.true, label %cond.end + +cond.true: +; CHECK-LABEL: cond.true: +; CHECK-NEXT: %1 = sext i32 %mul to i64 +; CHECK-NEXT: %2 = sext i32 %rem to i64 +; CHECK-NEXT: %sub22 = sub i64 %2, %1 +; CHECK-NOT: %sub22 = sext i32 %sub1 to i64 + %sub2 = sub nsw i32 %add, %mul + %idxprom = sext i32 %sub2 to i64 + %arryidx = getelementptr inbounds float, ptr %p, i64 %idxprom + store float 1.0, ptr %arryidx, align 4 + br label %cond.end + +cond.end: + %inc = add nuw nsw i32 %k, 1 + %exitcond = icmp ne i32 %inc, 100 + br i1 %exitcond, label %for.body, label %for.end + +for.end: + ret void +} + +declare i32 @foo() \ No newline at end of file