[llvm] bcfa0f5 - [InstCombine] Move negation handling into freelyNegateValue()
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 27 11:46:39 PST 2020
Author: Nikita Popov
Date: 2020-01-27T20:46:23+01:00
New Revision: bcfa0f592f8f2d4ced9e102a2881bd95a7197b16
URL: https://github.com/llvm/llvm-project/commit/bcfa0f592f8f2d4ced9e102a2881bd95a7197b16
DIFF: https://github.com/llvm/llvm-project/commit/bcfa0f592f8f2d4ced9e102a2881bd95a7197b16.diff
LOG: [InstCombine] Move negation handling into freelyNegateValue()
Followup to D72978. This moves existing negation handling in
InstCombine into freelyNegateValue(), which make it composable.
In particular, root negations of div/zext/sext/ashr/lshr/sub can
now always be performed through a shl/trunc as well.
Differential Revision: https://reviews.llvm.org/D73288
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 3f842f9e8d07..2f404856b173 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1734,22 +1734,18 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
}
if (Constant *C = dyn_cast<Constant>(Op0)) {
- bool IsNegate = match(C, m_ZeroInt());
+ // -f(x) -> f(-x) if possible.
+ if (match(C, m_Zero()))
+ if (Value *Neg = freelyNegateValue(Op1))
+ return replaceInstUsesWith(I, Neg);
+
Value *X;
- if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
- // 0 - (zext bool) --> sext bool
+ if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
// C - (zext bool) --> bool ? C - 1 : C
- if (IsNegate)
- return CastInst::CreateSExtOrBitCast(X, I.getType());
return SelectInst::Create(X, SubOne(C), C);
- }
- if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
- // 0 - (sext bool) --> zext bool
+ if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
// C - (sext bool) --> bool ? C + 1 : C
- if (IsNegate)
- return CastInst::CreateZExtOrBitCast(X, I.getType());
return SelectInst::Create(X, AddOne(C), C);
- }
// C - ~X == X + (1+C)
if (match(Op1, m_Not(m_Value(X))))
@@ -1778,51 +1774,15 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
const APInt *Op0C;
if (match(Op0, m_APInt(Op0C))) {
-
- if (Op0C->isNullValue()) {
- Value *Op1Wide;
- match(Op1, m_TruncOrSelf(m_Value(Op1Wide)));
- bool HadTrunc = Op1Wide != Op1;
- bool NoTruncOrTruncIsOneUse = !HadTrunc || Op1->hasOneUse();
- unsigned BitWidth = Op1Wide->getType()->getScalarSizeInBits();
-
- Value *X;
- const APInt *ShAmt;
- // -(X >>u 31) -> (X >>s 31)
- if (NoTruncOrTruncIsOneUse &&
- match(Op1Wide, m_LShr(m_Value(X), m_APInt(ShAmt))) &&
- *ShAmt == BitWidth - 1) {
- Value *ShAmtOp = cast<Instruction>(Op1Wide)->getOperand(1);
- Instruction *NewShift = BinaryOperator::CreateAShr(X, ShAmtOp);
- NewShift->copyIRFlags(Op1Wide);
- if (!HadTrunc)
- return NewShift;
- Builder.Insert(NewShift);
- return TruncInst::CreateTruncOrBitCast(NewShift, Op1->getType());
- }
- // -(X >>s 31) -> (X >>u 31)
- if (NoTruncOrTruncIsOneUse &&
- match(Op1Wide, m_AShr(m_Value(X), m_APInt(ShAmt))) &&
- *ShAmt == BitWidth - 1) {
- Value *ShAmtOp = cast<Instruction>(Op1Wide)->getOperand(1);
- Instruction *NewShift = BinaryOperator::CreateLShr(X, ShAmtOp);
- NewShift->copyIRFlags(Op1Wide);
- if (!HadTrunc)
- return NewShift;
- Builder.Insert(NewShift);
- return TruncInst::CreateTruncOrBitCast(NewShift, Op1->getType());
- }
-
- if (!HadTrunc && Op1->hasOneUse()) {
- Value *LHS, *RHS;
- SelectPatternFlavor SPF = matchSelectPattern(Op1, LHS, RHS).Flavor;
- if (SPF == SPF_ABS || SPF == SPF_NABS) {
- // This is a negate of an ABS/NABS pattern. Just swap the operands
- // of the select.
- cast<SelectInst>(Op1)->swapValues();
- // Don't swap prof metadata, we didn't change the branch behavior.
- return replaceInstUsesWith(I, Op1);
- }
+ if (Op0C->isNullValue() && Op1->hasOneUse()) {
+ Value *LHS, *RHS;
+ SelectPatternFlavor SPF = matchSelectPattern(Op1, LHS, RHS).Flavor;
+ if (SPF == SPF_ABS || SPF == SPF_NABS) {
+ // This is a negate of an ABS/NABS pattern. Just swap the operands
+ // of the select.
+ cast<SelectInst>(Op1)->swapValues();
+ // Don't swap prof metadata, we didn't change the branch behavior.
+ return replaceInstUsesWith(I, Op1);
}
}
@@ -1957,7 +1917,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
}
if (Op1->hasOneUse()) {
- Value *X = nullptr, *Y = nullptr, *Z = nullptr;
+ Value *Y = nullptr, *Z = nullptr;
Constant *C = nullptr;
// (X - (Y - Z)) --> (X + (Z - Y)).
@@ -1970,24 +1930,6 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateAnd(Op0,
Builder.CreateNot(Y, Y->getName() + ".not"));
- // 0 - (X sdiv C) -> (X sdiv -C) provided the negation doesn't overflow.
- if (match(Op0, m_Zero())) {
- Constant *Op11C;
- if (match(Op1, m_SDiv(m_Value(X), m_Constant(Op11C))) &&
- !Op11C->containsUndefElement() && Op11C->isNotMinSignedValue() &&
- Op11C->isNotOneValue()) {
- Instruction *BO =
- BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(Op11C));
- BO->setIsExact(cast<BinaryOperator>(Op1)->isExact());
- return BO;
- }
- }
-
- // 0 - (X << Y) -> (-X << Y) when X is freely negatable.
- if (match(Op1, m_Shl(m_Value(X), m_Value(Y))) && match(Op0, m_Zero()))
- if (Value *XNeg = freelyNegateValue(X))
- return BinaryOperator::CreateShl(XNeg, Y);
-
// Subtracting -1/0 is the same as adding 1/0:
// sub [nsw] Op0, sext(bool Y) -> add [nsw] Op0, zext(bool Y)
// 'nuw' is dropped in favor of the canonical form.
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 8dbad1a30c76..16ea6a2fbf7c 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -862,15 +862,82 @@ Value *InstCombiner::freelyNegateValue(Value *V) {
if (Value *NegV = dyn_castNegVal(V))
return NegV;
- if (!V->hasOneUse())
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (!I)
return nullptr;
- Value *A, *B;
+ unsigned BitWidth = I->getType()->getScalarSizeInBits();
+ switch (I->getOpcode()) {
+ // 0-(zext i1 A) => sext i1 A
+ case Instruction::ZExt:
+ if (I->getOperand(0)->getType()->isIntOrIntVectorTy(1))
+ return Builder.CreateSExtOrBitCast(
+ I->getOperand(0), I->getType(), I->getName() + ".neg");
+ return nullptr;
+
+ // 0-(sext i1 A) => zext i1 A
+ case Instruction::SExt:
+ if (I->getOperand(0)->getType()->isIntOrIntVectorTy(1))
+ return Builder.CreateZExtOrBitCast(
+ I->getOperand(0), I->getType(), I->getName() + ".neg");
+ return nullptr;
+
+ // 0-(A lshr (BW-1)) => A ashr (BW-1)
+ case Instruction::LShr:
+ if (match(I->getOperand(1), m_SpecificInt(BitWidth - 1)))
+ return Builder.CreateAShr(
+ I->getOperand(0), I->getOperand(1),
+ I->getName() + ".neg", cast<BinaryOperator>(I)->isExact());
+ return nullptr;
+
+ // 0-(A ashr (BW-1)) => A lshr (BW-1)
+ case Instruction::AShr:
+ if (match(I->getOperand(1), m_SpecificInt(BitWidth - 1)))
+ return Builder.CreateLShr(
+ I->getOperand(0), I->getOperand(1),
+ I->getName() + ".neg", cast<BinaryOperator>(I)->isExact());
+ return nullptr;
+
+ default:
+ break;
+ }
+
+ // TODO: The "sub" pattern below could also be applied without the one-use
+ // restriction. Not allowing it for now in line with existing behavior.
+ if (!I->hasOneUse())
+ return nullptr;
+
+ switch (I->getOpcode()) {
// 0-(A-B) => B-A
- if (match(V, m_Sub(m_Value(A), m_Value(B))))
- return Builder.CreateSub(B, A);
+ case Instruction::Sub:
+ return Builder.CreateSub(
+ I->getOperand(1), I->getOperand(0), I->getName() + ".neg");
+
+ // 0-(A sdiv C) => A sdiv (0-C) provided the negation doesn't overflow.
+ case Instruction::SDiv: {
+ Constant *C = dyn_cast<Constant>(I->getOperand(1));
+ if (C && !C->containsUndefElement() && C->isNotMinSignedValue() &&
+ C->isNotOneValue())
+ return Builder.CreateSDiv(I->getOperand(0), ConstantExpr::getNeg(C),
+ I->getName() + ".neg", cast<BinaryOperator>(I)->isExact());
+ return nullptr;
+ }
- return nullptr;
+ // 0-(A<<B) => (0-A)<<B
+ case Instruction::Shl:
+ if (Value *NegA = freelyNegateValue(I->getOperand(0)))
+ return Builder.CreateShl(NegA, I->getOperand(1), I->getName() + ".neg");
+ return nullptr;
+
+ // 0-(trunc A) => trunc (0-A)
+ case Instruction::Trunc:
+ if (Value *NegA = freelyNegateValue(I->getOperand(0)))
+ return Builder.CreateTrunc(NegA, I->getType(), I->getName() + ".neg");
+ return nullptr;
+
+ default:
+ return nullptr;
+ }
}
static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll
index cc96e9648eb6..29fb68292848 100644
--- a/llvm/test/Transforms/InstCombine/sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub.ll
@@ -300,8 +300,8 @@ define <2 x i1> @test11vec(<2 x i8> %A, <2 x i8> %B) {
define i32 @test12(i32 %A) {
; CHECK-LABEL: @test12(
-; CHECK-NEXT: [[C:%.*]] = lshr i32 [[A:%.*]], 31
-; CHECK-NEXT: ret i32 [[C]]
+; CHECK-NEXT: [[B_NEG:%.*]] = lshr i32 [[A:%.*]], 31
+; CHECK-NEXT: ret i32 [[B_NEG]]
;
%B = ashr i32 %A, 31
%C = sub i32 0, %B
@@ -310,8 +310,8 @@ define i32 @test12(i32 %A) {
define i32 @test13(i32 %A) {
; CHECK-LABEL: @test13(
-; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A:%.*]], 31
-; CHECK-NEXT: ret i32 [[C]]
+; CHECK-NEXT: [[B_NEG:%.*]] = ashr i32 [[A:%.*]], 31
+; CHECK-NEXT: ret i32 [[B_NEG]]
;
%B = lshr i32 %A, 31
%C = sub i32 0, %B
@@ -320,8 +320,8 @@ define i32 @test13(i32 %A) {
define <2 x i32> @test12vec(<2 x i32> %A) {
; CHECK-LABEL: @test12vec(
-; CHECK-NEXT: [[C:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 31, i32 31>
-; CHECK-NEXT: ret <2 x i32> [[C]]
+; CHECK-NEXT: [[B_NEG:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 31, i32 31>
+; CHECK-NEXT: ret <2 x i32> [[B_NEG]]
;
%B = ashr <2 x i32> %A, <i32 31, i32 31>
%C = sub <2 x i32> zeroinitializer, %B
@@ -330,8 +330,8 @@ define <2 x i32> @test12vec(<2 x i32> %A) {
define <2 x i32> @test13vec(<2 x i32> %A) {
; CHECK-LABEL: @test13vec(
-; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> [[A:%.*]], <i32 31, i32 31>
-; CHECK-NEXT: ret <2 x i32> [[C]]
+; CHECK-NEXT: [[B_NEG:%.*]] = ashr <2 x i32> [[A:%.*]], <i32 31, i32 31>
+; CHECK-NEXT: ret <2 x i32> [[B_NEG]]
;
%B = lshr <2 x i32> %A, <i32 31, i32 31>
%C = sub <2 x i32> zeroinitializer, %B
@@ -351,8 +351,8 @@ define i32 @test15(i32 %A, i32 %B) {
define i32 @test16(i32 %A) {
; CHECK-LABEL: @test16(
-; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[A:%.*]], -1123
-; CHECK-NEXT: ret i32 [[Y]]
+; CHECK-NEXT: [[X_NEG:%.*]] = sdiv i32 [[A:%.*]], -1123
+; CHECK-NEXT: ret i32 [[X_NEG]]
;
%X = sdiv i32 %A, 1123
%Y = sub i32 0, %X
@@ -507,8 +507,8 @@ define i64 @test24b(i8* %P, i64 %A){
define i64 @test25(i8* %P, i64 %A){
; CHECK-LABEL: @test25(
; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1
-; CHECK-NEXT: [[DIFF_NEG:%.*]] = add i64 [[B_IDX]], -84
-; CHECK-NEXT: ret i64 [[DIFF_NEG]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = add i64 [[B_IDX]], -84
+; CHECK-NEXT: ret i64 [[DOTNEG]]
;
%B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A
%C = ptrtoint i16* %B to i64
@@ -522,8 +522,8 @@ define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) {
; CHECK-LABEL: @test25_as1(
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i16
; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i16 [[TMP1]], 1
-; CHECK-NEXT: [[DIFF_NEG:%.*]] = add i16 [[B_IDX]], -84
-; CHECK-NEXT: ret i16 [[DIFF_NEG]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = add i16 [[B_IDX]], -84
+; CHECK-NEXT: ret i16 [[DOTNEG]]
;
%B = getelementptr inbounds [42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 0, i64 %A
%C = ptrtoint i16 addrspace(1)* %B to i16
@@ -533,8 +533,8 @@ define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) {
define i32 @test26(i32 %x) {
; CHECK-LABEL: @test26(
-; CHECK-NEXT: [[NEG:%.*]] = shl i32 -3, [[X:%.*]]
-; CHECK-NEXT: ret i32 [[NEG]]
+; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i32 -3, [[X:%.*]]
+; CHECK-NEXT: ret i32 [[SHL_NEG]]
;
%shl = shl i32 3, %x
%neg = sub i32 0, %shl
@@ -543,9 +543,9 @@ define i32 @test26(i32 %x) {
define i64 @test_neg_shl_sub(i64 %a, i64 %b) {
; CHECK-LABEL: @test_neg_shl_sub(
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
-; CHECK-NEXT: [[NEG:%.*]] = shl i64 [[TMP1]], 2
-; CHECK-NEXT: ret i64 [[NEG]]
+; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT: [[MUL_NEG:%.*]] = shl i64 [[SUB_NEG]], 2
+; CHECK-NEXT: ret i64 [[MUL_NEG]]
;
%sub = sub i64 %a, %b
%mul = shl i64 %sub, 2
@@ -585,10 +585,9 @@ define i64 @test_neg_shl_sub_extra_use2(i64 %a, i64 %b, i64* %p) {
define i64 @test_neg_shl_div(i64 %a) {
; CHECK-LABEL: @test_neg_shl_div(
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 [[A:%.*]], 3
-; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[DIV]], 2
-; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[SHL]]
-; CHECK-NEXT: ret i64 [[NEG]]
+; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv i64 [[A:%.*]], -3
+; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[DIV_NEG]], 2
+; CHECK-NEXT: ret i64 [[SHL_NEG]]
;
%div = sdiv i64 %a, 3
%shl = shl i64 %div, 2
@@ -598,10 +597,9 @@ define i64 @test_neg_shl_div(i64 %a) {
define i64 @test_neg_shl_zext_i1(i1 %a, i64 %b) {
; CHECK-LABEL: @test_neg_shl_zext_i1(
-; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[A:%.*]] to i64
-; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[EXT]], [[B:%.*]]
-; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[SHL]]
-; CHECK-NEXT: ret i64 [[NEG]]
+; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64
+; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[EXT_NEG]], [[B:%.*]]
+; CHECK-NEXT: ret i64 [[SHL_NEG]]
;
%ext = zext i1 %a to i64
%shl = shl i64 %ext, %b
@@ -611,10 +609,9 @@ define i64 @test_neg_shl_zext_i1(i1 %a, i64 %b) {
define i64 @test_neg_shl_sext_i1(i1 %a, i64 %b) {
; CHECK-LABEL: @test_neg_shl_sext_i1(
-; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[A:%.*]] to i64
-; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[EXT]], [[B:%.*]]
-; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[SHL]]
-; CHECK-NEXT: ret i64 [[NEG]]
+; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64
+; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[EXT_NEG]], [[B:%.*]]
+; CHECK-NEXT: ret i64 [[SHL_NEG]]
;
%ext = sext i1 %a to i64
%shl = shl i64 %ext, %b
@@ -625,9 +622,9 @@ define i64 @test_neg_shl_sext_i1(i1 %a, i64 %b) {
define i64 @test_neg_zext_i1_extra_use(i1 %a, i64 %b, i64* %p) {
; CHECK-LABEL: @test_neg_zext_i1_extra_use(
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[A:%.*]] to i64
-; CHECK-NEXT: [[NEG:%.*]] = sext i1 [[A]] to i64
+; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[A]] to i64
; CHECK-NEXT: store i64 [[EXT]], i64* [[P:%.*]], align 8
-; CHECK-NEXT: ret i64 [[NEG]]
+; CHECK-NEXT: ret i64 [[EXT_NEG]]
;
%ext = zext i1 %a to i64
%neg = sub i64 0, %ext
@@ -638,9 +635,9 @@ define i64 @test_neg_zext_i1_extra_use(i1 %a, i64 %b, i64* %p) {
define i64 @test_neg_sext_i1_extra_use(i1 %a, i64 %b, i64* %p) {
; CHECK-LABEL: @test_neg_sext_i1_extra_use(
; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[A:%.*]] to i64
-; CHECK-NEXT: [[NEG:%.*]] = zext i1 [[A]] to i64
+; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A]] to i64
; CHECK-NEXT: store i64 [[EXT]], i64* [[P:%.*]], align 8
-; CHECK-NEXT: ret i64 [[NEG]]
+; CHECK-NEXT: ret i64 [[EXT_NEG]]
;
%ext = sext i1 %a to i64
%neg = sub i64 0, %ext
@@ -650,11 +647,10 @@ define i64 @test_neg_sext_i1_extra_use(i1 %a, i64 %b, i64* %p) {
define i32 @test_neg_trunc_shl_sub(i64 %a, i64 %b) {
; CHECK-LABEL: @test_neg_trunc_shl_sub(
-; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[SUB_TR:%.*]] = trunc i64 [[SUB]] to i32
-; CHECK-NEXT: [[TRUNC:%.*]] = shl i32 [[SUB_TR]], 2
-; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[TRUNC]]
-; CHECK-NEXT: ret i32 [[NEG]]
+; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT: [[SUB_TR_NEG:%.*]] = trunc i64 [[SUB_NEG]] to i32
+; CHECK-NEXT: [[TRUNC_NEG:%.*]] = shl i32 [[SUB_TR_NEG]], 2
+; CHECK-NEXT: ret i32 [[TRUNC_NEG]]
;
%sub = sub i64 %a, %b
%shl = shl i64 %sub, 2
@@ -665,11 +661,10 @@ define i32 @test_neg_trunc_shl_sub(i64 %a, i64 %b) {
define i32 @test_neg_trunc_shl_ashr(i64 %a, i64 %b) {
; CHECK-LABEL: @test_neg_trunc_shl_ashr(
-; CHECK-NEXT: [[SHR:%.*]] = ashr i64 [[A:%.*]], 63
-; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[SHR]], [[B:%.*]]
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[SHL]] to i32
-; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[TRUNC]]
-; CHECK-NEXT: ret i32 [[NEG]]
+; CHECK-NEXT: [[SHR_NEG:%.*]] = lshr i64 [[A:%.*]], 63
+; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[SHR_NEG]], [[B:%.*]]
+; CHECK-NEXT: [[TRUNC_NEG:%.*]] = trunc i64 [[SHL_NEG]] to i32
+; CHECK-NEXT: ret i32 [[TRUNC_NEG]]
;
%shr = ashr i64 %a, 63
%shl = shl i64 %shr, %b
@@ -680,11 +675,10 @@ define i32 @test_neg_trunc_shl_ashr(i64 %a, i64 %b) {
define i32 @test_neg_trunc_shl_lshr(i64 %a, i64 %b) {
; CHECK-LABEL: @test_neg_trunc_shl_lshr(
-; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[A:%.*]], 63
-; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[SHR]], [[B:%.*]]
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[SHL]] to i32
-; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[TRUNC]]
-; CHECK-NEXT: ret i32 [[NEG]]
+; CHECK-NEXT: [[SHR_NEG:%.*]] = ashr i64 [[A:%.*]], 63
+; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[SHR_NEG]], [[B:%.*]]
+; CHECK-NEXT: [[TRUNC_NEG:%.*]] = trunc i64 [[SHL_NEG]] to i32
+; CHECK-NEXT: ret i32 [[TRUNC_NEG]]
;
%shr = lshr i64 %a, 63
%shl = shl i64 %shr, %b
@@ -835,8 +829,8 @@ define i32 @test28commuted(i32 %x, i32 %y, i32 %z) {
define i64 @test29(i8* %foo, i64 %i, i64 %j) {
; CHECK-LABEL: @test29(
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
-; CHECK-NEXT: ret i64 [[TMP1]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
+; CHECK-NEXT: ret i64 [[DOTNEG]]
;
%gep1 = getelementptr inbounds i8, i8* %foo, i64 %i
%gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
@@ -849,8 +843,8 @@ define i64 @test29(i8* %foo, i64 %i, i64 %j) {
define i64 @test30(i8* %foo, i64 %i, i64 %j) {
; CHECK-LABEL: @test30(
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[GEP1_IDX]], [[J:%.*]]
-; CHECK-NEXT: ret i64 [[TMP1]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = sub i64 [[GEP1_IDX]], [[J:%.*]]
+; CHECK-NEXT: ret i64 [[DOTNEG]]
;
%bit = bitcast i8* %foo to i32*
%gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
@@ -864,8 +858,8 @@ define i64 @test30(i8* %foo, i64 %i, i64 %j) {
define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
; CHECK-LABEL: @test30_as1(
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
-; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[GEP1_IDX]], [[J:%.*]]
-; CHECK-NEXT: ret i16 [[TMP1]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = sub i16 [[GEP1_IDX]], [[J:%.*]]
+; CHECK-NEXT: ret i16 [[DOTNEG]]
;
%bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
%gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
@@ -919,8 +913,8 @@ define <2 x i64> @test36(<2 x i64> %A) {
define <2 x i32> @test37(<2 x i32> %A) {
; CHECK-LABEL: @test37(
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -2147483648, i32 -2147483648>
-; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32>
-; CHECK-NEXT: ret <2 x i32> [[SUB]]
+; CHECK-NEXT: [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32>
+; CHECK-NEXT: ret <2 x i32> [[DIV_NEG]]
;
%div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
%sub = sub nsw <2 x i32> zeroinitializer, %div
@@ -930,8 +924,8 @@ define <2 x i32> @test37(<2 x i32> %A) {
define i32 @test38(i32 %A) {
; CHECK-LABEL: @test38(
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -2147483648
-; CHECK-NEXT: [[SUB:%.*]] = sext i1 [[TMP1]] to i32
-; CHECK-NEXT: ret i32 [[SUB]]
+; CHECK-NEXT: [[DIV_NEG:%.*]] = sext i1 [[TMP1]] to i32
+; CHECK-NEXT: ret i32 [[DIV_NEG]]
;
%div = sdiv i32 %A, -2147483648
%sub = sub nsw i32 0, %div
@@ -1246,8 +1240,8 @@ define i64 @test58([100 x [100 x i8]]* %foo, i64 %i, i64 %j) {
; CHECK-LABEL: @test58(
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add i64 [[J:%.*]], 4200
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add i64 [[I:%.*]], 4200
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
-; CHECK-NEXT: ret i64 [[TMP1]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = sub i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
+; CHECK-NEXT: ret i64 [[DOTNEG]]
;
%gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i
%gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %j
More information about the llvm-commits
mailing list