Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -1183,6 +1183,22 @@ bool MathDominates = DT.dominates(BO, Cmp); if (!MathDominates && !DT.dominates(Cmp, BO)) return false; + + // Check that the insertion doesn't create a value that is live across more + // than two blocks, so to minimise the increase in register pressure. + DT.updateDFSNumbers(); + auto MathNode = DT.getNode(BO->getParent()); + auto CmpNode = DT.getNode(Cmp->getParent()); + unsigned MathD = MathNode->getDFSNumIn(); + unsigned MathF = MathNode->getDFSNumOut(); + unsigned CmpD = CmpNode->getDFSNumIn(); + unsigned CmpF = CmpNode->getDFSNumOut(); + unsigned Distance = MathDominates ? + std::min(CmpD - MathD, MathF - CmpF) : + std::min(MathD - CmpD, CmpF - MathF); + if (Distance > 2) + return false; + InsertPt = MathDominates ? cast(BO) : cast(Cmp); } Index: test/Transforms/CodeGenPrepare/ARM/overflow-intrinsics.ll =================================================================== --- /dev/null +++ test/Transforms/CodeGenPrepare/ARM/overflow-intrinsics.ll @@ -0,0 +1,72 @@ +; RUN: opt -codegenprepare -S < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv8m.main-arm-none-eabi" + +; CHECK-LABEL: uadd_overflow_too_far_cmp_dom +; CHECK-NOT: with.overflow.i32 +define i32 @uadd_overflow_too_far_cmp_dom(i32 %arg0) { +entry: + %cmp = icmp ne i32 %arg0, 0 + br i1 %cmp, label %if.else, label %if.then + +if.then: + call void @foo() + br label %exit + +if.else: + %cmp.i = icmp ugt i32 %arg0, 1 + br i1 %cmp.i, label %if.else.i, label %if.then.i + +if.else.i: + call void @foo() + br label %if.end + +if.then.i: + call void @bar() + br label %if.end + +if.end: + %dec = add nsw i32 %arg0, -1 + br label %exit + +exit: + %res = phi i32 [ %arg0, %if.then ], [ %dec, %if.end ] + ret i32 %res +} + +; CHECK-LABEL: uadd_overflow_too_far_math_dom +; CHECK-NOT: with.overflow.i32 +define i32 @uadd_overflow_too_far_math_dom(i32 %arg0, i32 %arg1) { +entry: + %dec = add nsw i32 %arg0, -1 + %cmp = icmp ugt i32 %arg0, 1 + br i1 %cmp, label %if.else, label %if.then + +if.then: + call void @foo() + br label %if.end + +if.else: + call void @bar() + br label %if.end + +if.end: + %cmp.i = icmp ne i32 %arg1, 0 + br i1 %cmp.i, label %if.else.i, label %if.then.i + +if.else.i: + br label %exit + +if.then.i: + %cmp.i.i = icmp ne i32 %arg0, 0 + %tobool = zext i1 %cmp.i.i to i32 + br label %exit + +exit: + %res = phi i32 [ %dec, %if.else.i ], [ %tobool, %if.then.i ] + ret i32 %res +} + +declare void @foo() +declare void @bar()