From 3e01ae9f8f9f7cc8c2c6fd93111ee9282b5a004c Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 2 Jul 2014 06:42:13 +0000 Subject: [PATCH] InstCombine: Optimize x/INT_MIN to x==INT_MIN The result of x/INT_MIN is either 0 or 1, we can just use an icmp instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212167 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 4 ++++ test/Transforms/InstCombine/sub.ll | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 497c0b49ab3..6c6e7d81516 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -993,6 +993,10 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) { } if (Constant *RHS = dyn_cast(Op1)) { + // X/INT_MIN -> X == INT_MIN + if (RHS->isMinSignedValue()) + return new ZExtInst(Builder->CreateICmpEQ(Op0, Op1), I.getType()); + // -X/C --> X/-C provided the negation doesn't overflow. if (SubOperator *Sub = dyn_cast(Op0)) if (match(Sub->getOperand(0), m_Zero()) && Sub->hasNoSignedWrap()) diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll index 5ff0ed5b40c..67b7c4996b0 100644 --- a/test/Transforms/InstCombine/sub.ll +++ b/test/Transforms/InstCombine/sub.ll @@ -450,9 +450,9 @@ define <2 x i32> @test37(<2 x i32> %A) { %sub = sub nsw <2 x i32> zeroinitializer, %div ret <2 x i32> %sub ; CHECK-LABEL: @test37( -; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> %A, -; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %div -; CHECK-NEXT: ret <2 x i32> [[SUB]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> %A, +; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[ICMP]] to <2 x i32> +; CHECK-NEXT: ret <2 x i32> [[SEXT]] } define i32 @test38(i32 %A) { @@ -460,7 +460,7 @@ define i32 @test38(i32 %A) { %sub = sub nsw i32 0, %div ret i32 %sub ; CHECK-LABEL: @test38( -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %A, -2147483648 -; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[DIV]] -; CHECK-NEXT: ret i32 [[SUB]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 %A, -2147483648 +; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i32 +; CHECK-NEXT: ret i32 [[SEXT]] } -- 2.34.1