[llvm] r364235 - InstCombine: Preserve nuw when reassociating nuw ops [3/3]
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 24 14:37:03 PDT 2019
Author: arsenm
Date: Mon Jun 24 14:37:03 2019
New Revision: 364235
URL: http://llvm.org/viewvc/llvm-project?rev=364235&view=rev
Log:
InstCombine: Preserve nuw when reassociating nuw ops [3/3]
Alive says this is OK.
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=364235&r1=364234&r2=364235&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon Jun 24 14:37:03 2019
@@ -590,32 +590,44 @@ Value *InstCombiner::tryFactorization(Bi
++NumFactor;
SimplifiedInst->takeName(&I);
- // Check if we can add NSW flag to SimplifiedInst. If so, set NSW flag.
- // TODO: Check for NUW.
+ // Check if we can add NSW/NUW flags to SimplifiedInst. If so, set them.
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SimplifiedInst)) {
if (isa<OverflowingBinaryOperator>(SimplifiedInst)) {
bool HasNSW = false;
- if (isa<OverflowingBinaryOperator>(&I))
+ bool HasNUW = false;
+ if (isa<OverflowingBinaryOperator>(&I)) {
HasNSW = I.hasNoSignedWrap();
+ HasNUW = I.hasNoUnsignedWrap();
+ }
- if (auto *LOBO = dyn_cast<OverflowingBinaryOperator>(LHS))
+ if (auto *LOBO = dyn_cast<OverflowingBinaryOperator>(LHS)) {
HasNSW &= LOBO->hasNoSignedWrap();
+ HasNUW &= LOBO->hasNoUnsignedWrap();
+ }
- if (auto *ROBO = dyn_cast<OverflowingBinaryOperator>(RHS))
+ if (auto *ROBO = dyn_cast<OverflowingBinaryOperator>(RHS)) {
HasNSW &= ROBO->hasNoSignedWrap();
+ HasNUW &= ROBO->hasNoUnsignedWrap();
+ }
- // We can propagate 'nsw' if we know that
- // %Y = mul nsw i16 %X, C
- // %Z = add nsw i16 %Y, %X
- // =>
- // %Z = mul nsw i16 %X, C+1
- //
- // iff C+1 isn't INT_MIN
const APInt *CInt;
if (TopLevelOpcode == Instruction::Add &&
- InnerOpcode == Instruction::Mul)
- if (match(V, m_APInt(CInt)) && !CInt->isMinSignedValue())
- BO->setHasNoSignedWrap(HasNSW);
+ InnerOpcode == Instruction::Mul) {
+ // We can propagate 'nsw' if we know that
+ // %Y = mul nsw i16 %X, C
+ // %Z = add nsw i16 %Y, %X
+ // =>
+ // %Z = mul nsw i16 %X, C+1
+ //
+ // iff C+1 isn't INT_MIN
+ if (match(V, m_APInt(CInt))) {
+ if (!CInt->isMinSignedValue())
+ BO->setHasNoSignedWrap(HasNSW);
+ }
+
+ // nuw can be propagated with any constant or nuw value.
+ BO->setHasNoUnsignedWrap(HasNUW);
+ }
}
}
}
Modified: llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll?rev=364235&r1=364234&r2=364235&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll Mon Jun 24 14:37:03 2019
@@ -92,7 +92,7 @@ define i32 @reassoc_x2_sub_nuw(i32 %x, i
define i32 @tryFactorization_add_nuw_mul_nuw(i32 %x) {
; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw(
-; CHECK-NEXT: [[ADD2:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT: [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 2
; CHECK-NEXT: ret i32 [[ADD2]]
;
%mul1 = mul nuw i32 %x, 3
@@ -102,7 +102,7 @@ define i32 @tryFactorization_add_nuw_mul
define i32 @tryFactorization_add_nuw_mul_nuw_int_max(i32 %x) {
; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_int_max(
-; CHECK-NEXT: [[ADD2:%.*]] = shl i32 [[X:%.*]], 31
+; CHECK-NEXT: [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 31
; CHECK-NEXT: ret i32 [[ADD2]]
;
%mul1 = mul nuw i32 %x, 2147483647
@@ -129,3 +129,51 @@ define i32 @tryFactorization_add_nuw_mul
%add2 = add i32 %mul1, %x
ret i32 %add2
}
+
+define i32 @tryFactorization_add_nuw_mul_nuw_mul_nuw_var(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_nuw_var(
+; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[ADD1:%.*]] = mul nuw i32 [[MUL21]], [[X:%.*]]
+; CHECK-NEXT: ret i32 [[ADD1]]
+;
+ %mul1 = mul nuw i32 %x, %y
+ %mul2 = mul nuw i32 %x, %z
+ %add1 = add nuw i32 %mul1, %mul2
+ ret i32 %add1
+}
+
+define i32 @tryFactorization_add_nuw_mul_mul_nuw_var(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @tryFactorization_add_nuw_mul_mul_nuw_var(
+; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[MUL21]], [[X:%.*]]
+; CHECK-NEXT: ret i32 [[ADD1]]
+;
+ %mul1 = mul i32 %x, %y
+ %mul2 = mul nuw i32 %x, %z
+ %add1 = add nuw i32 %mul1, %mul2
+ ret i32 %add1
+}
+
+define i32 @tryFactorization_add_nuw_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_var(
+; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[MUL21]], [[X:%.*]]
+; CHECK-NEXT: ret i32 [[ADD1]]
+;
+ %mul1 = mul nuw i32 %x, %y
+ %mul2 = mul i32 %x, %z
+ %add1 = add nuw i32 %mul1, %mul2
+ ret i32 %add1
+}
+
+define i32 @tryFactorization_add_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @tryFactorization_add_mul_nuw_mul_var(
+; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[MUL21]], [[X:%.*]]
+; CHECK-NEXT: ret i32 [[ADD1]]
+;
+ %mul1 = mul nuw i32 %x, %y
+ %mul2 = mul nuw i32 %x, %z
+ %add1 = add i32 %mul1, %mul2
+ ret i32 %add1
+}
More information about the llvm-commits
mailing list