From: Chen Zheng Date: Sat, 13 Apr 2019 09:21:22 +0000 (+0000) Subject: [InstCombine] Canonicalize (-X srem Y) to -(X srem Y). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83034dffa4d6a5db17e117d5e649542d827f2169;p=llvm [InstCombine] Canonicalize (-X srem Y) to -(X srem Y). Differential Revision: https://reviews.llvm.org/D60647 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358328 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index e53eac2dd4e..7edae55cb3e 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1351,6 +1351,11 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) { } } + // -X srem Y --> -(X srem Y) + Value *X, *Y; + if (match(&I, m_SRem(m_OneUse(m_NSWSub(m_Zero(), m_Value(X))), m_Value(Y)))) + return BinaryOperator::CreateNSWNeg(Builder.CreateSRem(X, Y)); + // If the sign bits of both operands are zero (i.e. we can prove they are // unsigned inputs), turn this into a urem. APInt Mask(APInt::getSignMask(I.getType()->getScalarSizeInBits())); diff --git a/test/Transforms/InstCombine/srem-canonicalize.ll b/test/Transforms/InstCombine/srem-canonicalize.ll index af27fd3affa..dc6b15c287c 100644 --- a/test/Transforms/InstCombine/srem-canonicalize.ll +++ b/test/Transforms/InstCombine/srem-canonicalize.ll @@ -3,8 +3,8 @@ define i32 @test_srem_canonicalize_op0(i32 %x, i32 %y) { ; CHECK-LABEL: @test_srem_canonicalize_op0( -; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]] -; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[NEG]], [[Y:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = srem i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[SREM:%.*]] = sub nsw i32 0, [[TMP1]] ; CHECK-NEXT: ret i32 [[SREM]] ; %neg = sub nsw i32 0, %x @@ -39,8 +39,8 @@ define i32 @test_srem_canonicalize_nonsw(i32 %x, i32 %y) { define <2 x i32> @test_srem_canonicalize_vec(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @test_srem_canonicalize_vec( -; CHECK-NEXT: [[NEG:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]] -; CHECK-NEXT: [[SREM:%.*]] = srem <2 x i32> [[NEG]], [[Y:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = srem <2 x i32> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[SREM:%.*]] = sub nsw <2 x i32> zeroinitializer, [[TMP1]] ; CHECK-NEXT: ret <2 x i32> [[SREM]] ; %neg = sub nsw <2 x i32> , %x