[llvm] [InstCombine] Fold mul (lshr exact (X, N)), 2^N + 1 -> add (X , lshr exact (X, N)) (PR #95042)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 20 09:09:44 PDT 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/95042
>From 0874c2335ae5d69d04fd80b9cef0141c6d8714c9 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Mon, 10 Jun 2024 12:44:49 -0400
Subject: [PATCH 1/7] [InstCombine] Pre-commit test (NFC)
---
llvm/test/Transforms/InstCombine/ashr-lshr.ll | 122 ++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/ashr-lshr.ll b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
index c2a4f35412670..682435ec5cb1b 100644
--- a/llvm/test/Transforms/InstCombine/ashr-lshr.ll
+++ b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
@@ -862,4 +862,126 @@ define i32 @ashr_mul_times_5_div_4_exact_2(i32 %x) {
ret i32 %ashr
}
+define i32 @ashr_shift_mul(i32 %x) {
+; CHECK-LABEL: @ashr_shift_mul(
+; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = ashr exact i32 %x, 3
+ %res = mul i32 %a, 9
+ ret i32 %res
+}
+
+define i32 @ashr_shift_mul_nuw(i32 %x) {
+; CHECK-LABEL: @ashr_shift_mul_nuw(
+; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = ashr exact i32 %x, 3
+ %res = mul nuw i32 %a, 9
+ ret i32 %res
+}
+
+define i32 @ashr_shift_mul_nsw(i32 %x) {
+; CHECK-LABEL: @ashr_shift_mul_nsw(
+; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = ashr exact i32 %x, 3
+ %res = mul nsw i32 %a, 9
+ ret i32 %res
+}
+
+define i32 @lshr_shift_mul_nuw(i32 %x) {
+; CHECK-LABEL: @lshr_shift_mul_nuw(
+; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = lshr exact i32 %x, 3
+ %res = mul nuw i32 %a, 9
+ ret i32 %res
+}
+
+define i32 @lshr_shift_mul(i32 %x) {
+; CHECK-LABEL: @lshr_shift_mul(
+; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = lshr exact i32 %x, 3
+ %res = mul i32 %a, 9
+ ret i32 %res
+}
+
+define i32 @lshr_shift_mul_nsw(i32 %x) {
+; CHECK-LABEL: @lshr_shift_mul_nsw(
+; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = lshr exact i32 %x, 3
+ %res = mul nsw i32 %a, 9
+ ret i32 %res
+}
+
+; Negative test
+
+define i32 @lshr_no_exact(i32 %x) {
+; CHECK-LABEL: @lshr_no_exact(
+; CHECK-NEXT: [[A:%.*]] = lshr i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = lshr i32 %x, 3
+ %res = mul nsw i32 %a, 9
+ ret i32 %res
+}
+
+; Negative test
+
+define i32 @ashr_no_exact(i32 %x) {
+; CHECK-LABEL: @ashr_no_exact(
+; CHECK-NEXT: [[A:%.*]] = ashr i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = ashr i32 %x, 3
+ %res = mul nsw i32 %a, 9
+ ret i32 %res
+}
+
+; Negative test
+
+define i32 @lshr_multiuse(i32 %x) {
+; CHECK-LABEL: @lshr_multiuse(
+; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: call void @use(i32 [[A]])
+; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = lshr exact i32 %x, 3
+ call void @use(i32 %a)
+ %res = mul nsw i32 %a, 9
+ ret i32 %res
+}
+
+; Negative test
+
+define i32 @ashr_multiuse(i32 %x) {
+; CHECK-LABEL: @ashr_multiuse(
+; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: call void @use(i32 [[A]])
+; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = ashr exact i32 %x, 3
+ call void @use(i32 %a)
+ %res = mul nsw i32 %a, 9
+ ret i32 %res
+}
+
declare void @use(i32)
>From 24e2d78749ea90fe7bc5e6d02fbb593ca371411d Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Mon, 10 Jun 2024 12:47:14 -0400
Subject: [PATCH 2/7] [InstCombine] Fold mul (lshr exact (X, 2^N + 1)), N ->
add (X , lshr (X, N))
Alive2 Proofs:
https://alive2.llvm.org/ce/z/LVqGEo
https://alive2.llvm.org/ce/z/dyeGEv
---
.../InstCombine/InstCombineMulDivRem.cpp | 32 +++++++++++++
llvm/test/Transforms/InstCombine/ashr-lshr.ll | 45 +++++++++++++++----
2 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index ca1b1921404d8..106d1daec95f5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -255,6 +255,38 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
}
}
+ {
+ // mul (lshr exact X, N), (2^N + 1) -> add (X , lshr (X, N))
+ Value *NewOp;
+ const APInt *ShiftC;
+ const APInt *MulAP;
+ if ((HasNSW || HasNUW) &&
+ match(&I, m_Mul(m_CombineOr(m_LShr(m_Value(NewOp), m_APInt(ShiftC)),
+ m_AShr(m_Value(NewOp), m_APInt(ShiftC))),
+ m_APInt(MulAP)))) {
+ if (BitWidth > 2 && (*MulAP - 1).isPowerOf2() &&
+ MulAP->logBase2() == ShiftC->getZExtValue()) {
+ BinaryOperator *OpBO = cast<BinaryOperator>(Op0);
+ if (OpBO->isExact()) {
+ Value *BinOp = Op0;
+ if (HasNUW && OpBO->getOpcode() == Instruction::AShr &&
+ OpBO->hasOneUse())
+ BinOp = Builder.CreateLShr(
+ NewOp, ConstantInt::get(Ty, ShiftC->getZExtValue()), "",
+ /*isExact=*/true);
+
+ auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp);
+ if (HasNSW && (OpBO->getOpcode() == Instruction::LShr ||
+ ShiftC->getZExtValue() < BitWidth - 1))
+ NewAdd->setHasNoSignedWrap(true);
+
+ NewAdd->setHasNoUnsignedWrap(HasNUW);
+ return NewAdd;
+ }
+ }
+ }
+ }
+
if (Op0->hasOneUse() && match(Op1, m_NegatedPower2())) {
// Interpret X * (-1<<C) as (-X) * (1<<C) and try to sink the negation.
// The "* (1<<C)" thus becomes a potential shifting opportunity.
diff --git a/llvm/test/Transforms/InstCombine/ashr-lshr.ll b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
index 682435ec5cb1b..dfb1879da076b 100644
--- a/llvm/test/Transforms/InstCombine/ashr-lshr.ll
+++ b/llvm/test/Transforms/InstCombine/ashr-lshr.ll
@@ -875,8 +875,8 @@ define i32 @ashr_shift_mul(i32 %x) {
define i32 @ashr_shift_mul_nuw(i32 %x) {
; CHECK-LABEL: @ashr_shift_mul_nuw(
-; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
-; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], 9
+; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: [[RES:%.*]] = add nuw i32 [[TMP1]], [[X]]
; CHECK-NEXT: ret i32 [[RES]]
;
%a = ashr exact i32 %x, 3
@@ -887,7 +887,7 @@ define i32 @ashr_shift_mul_nuw(i32 %x) {
define i32 @ashr_shift_mul_nsw(i32 %x) {
; CHECK-LABEL: @ashr_shift_mul_nsw(
; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
-; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
+; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[A]], [[X]]
; CHECK-NEXT: ret i32 [[RES]]
;
%a = ashr exact i32 %x, 3
@@ -898,7 +898,7 @@ define i32 @ashr_shift_mul_nsw(i32 %x) {
define i32 @lshr_shift_mul_nuw(i32 %x) {
; CHECK-LABEL: @lshr_shift_mul_nuw(
; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
-; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], 9
+; CHECK-NEXT: [[RES:%.*]] = add nuw i32 [[A]], [[X]]
; CHECK-NEXT: ret i32 [[RES]]
;
%a = lshr exact i32 %x, 3
@@ -920,7 +920,7 @@ define i32 @lshr_shift_mul(i32 %x) {
define i32 @lshr_shift_mul_nsw(i32 %x) {
; CHECK-LABEL: @lshr_shift_mul_nsw(
; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
-; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
+; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[A]], [[X]]
; CHECK-NEXT: ret i32 [[RES]]
;
%a = lshr exact i32 %x, 3
@@ -954,13 +954,11 @@ define i32 @ashr_no_exact(i32 %x) {
ret i32 %res
}
-; Negative test
-
define i32 @lshr_multiuse(i32 %x) {
; CHECK-LABEL: @lshr_multiuse(
; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
; CHECK-NEXT: call void @use(i32 [[A]])
-; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
+; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[A]], [[X]]
; CHECK-NEXT: ret i32 [[RES]]
;
%a = lshr exact i32 %x, 3
@@ -969,13 +967,42 @@ define i32 @lshr_multiuse(i32 %x) {
ret i32 %res
}
+
+; Negative test
+
+define i32 @lshr_multiuse_no_flags(i32 %x) {
+; CHECK-LABEL: @lshr_multiuse_no_flags(
+; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: call void @use(i32 [[A]])
+; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = lshr exact i32 %x, 3
+ call void @use(i32 %a)
+ %res = mul i32 %a, 9
+ ret i32 %res
+}
+
; Negative test
+define i32 @ashr_multiuse_no_flags(i32 %x) {
+; CHECK-LABEL: @ashr_multiuse_no_flags(
+; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
+; CHECK-NEXT: call void @use(i32 [[A]])
+; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
+; CHECK-NEXT: ret i32 [[RES]]
+;
+ %a = ashr exact i32 %x, 3
+ call void @use(i32 %a)
+ %res = mul i32 %a, 9
+ ret i32 %res
+}
+
define i32 @ashr_multiuse(i32 %x) {
; CHECK-LABEL: @ashr_multiuse(
; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
; CHECK-NEXT: call void @use(i32 [[A]])
-; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
+; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[A]], [[X]]
; CHECK-NEXT: ret i32 [[RES]]
;
%a = ashr exact i32 %x, 3
>From 7faf9afb43feda9173a9bd22c0c849a40aa5e67c Mon Sep 17 00:00:00 2001
From: AtariDreams <gfunni234 at gmail.com>
Date: Thu, 20 Jun 2024 11:49:27 -0400
Subject: [PATCH 3/7] Update InstCombineMulDivRem.cpp
Co-authored-by: Nikita Popov <github at npopov.com>
---
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 106d1daec95f5..cf10c1f3e924d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -261,8 +261,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
const APInt *ShiftC;
const APInt *MulAP;
if ((HasNSW || HasNUW) &&
- match(&I, m_Mul(m_CombineOr(m_LShr(m_Value(NewOp), m_APInt(ShiftC)),
- m_AShr(m_Value(NewOp), m_APInt(ShiftC))),
+ match(&I, m_Mul(m_Shr(m_Value(NewOp), m_APInt(ShiftC)),
m_APInt(MulAP)))) {
if (BitWidth > 2 && (*MulAP - 1).isPowerOf2() &&
MulAP->logBase2() == ShiftC->getZExtValue()) {
>From 502d851bab92dfc2f7413bc2744b9db55a90faef Mon Sep 17 00:00:00 2001
From: AtariDreams <gfunni234 at gmail.com>
Date: Thu, 20 Jun 2024 11:49:32 -0400
Subject: [PATCH 4/7] Update InstCombineMulDivRem.cpp
Co-authored-by: Nikita Popov <github at npopov.com>
---
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index cf10c1f3e924d..0be6bc2934e52 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -264,7 +264,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
match(&I, m_Mul(m_Shr(m_Value(NewOp), m_APInt(ShiftC)),
m_APInt(MulAP)))) {
if (BitWidth > 2 && (*MulAP - 1).isPowerOf2() &&
- MulAP->logBase2() == ShiftC->getZExtValue()) {
+ ShiftC == MulAP->logBase2()) {
BinaryOperator *OpBO = cast<BinaryOperator>(Op0);
if (OpBO->isExact()) {
Value *BinOp = Op0;
>From ad97e167cd7e939de03c992fd4cdb6d54ca8efac Mon Sep 17 00:00:00 2001
From: AtariDreams <gfunni234 at gmail.com>
Date: Thu, 20 Jun 2024 11:49:38 -0400
Subject: [PATCH 5/7] Update InstCombineMulDivRem.cpp
Co-authored-by: Nikita Popov <github at npopov.com>
---
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 0be6bc2934e52..f2a1a6d9246f7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -271,7 +271,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
if (HasNUW && OpBO->getOpcode() == Instruction::AShr &&
OpBO->hasOneUse())
BinOp = Builder.CreateLShr(
- NewOp, ConstantInt::get(Ty, ShiftC->getZExtValue()), "",
+ NewOp, ConstantInt::get(Ty, ShiftC), "",
/*isExact=*/true);
auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp);
>From 9bcfc92845f369ea5f028006592160683b66c3ec Mon Sep 17 00:00:00 2001
From: AtariDreams <gfunni234 at gmail.com>
Date: Thu, 20 Jun 2024 12:03:42 -0400
Subject: [PATCH 6/7] Update InstCombineMulDivRem.cpp
---
.../InstCombine/InstCombineMulDivRem.cpp | 36 +++++++++----------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index f2a1a6d9246f7..2e8d082e52e11 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -256,32 +256,30 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
}
{
- // mul (lshr exact X, N), (2^N + 1) -> add (X , lshr (X, N))
+ // mul (lshr exact X, N), (2^N + 1) -> add (X , lshr exact (X, N))
Value *NewOp;
const APInt *ShiftC;
const APInt *MulAP;
if ((HasNSW || HasNUW) &&
- match(&I, m_Mul(m_Shr(m_Value(NewOp), m_APInt(ShiftC)),
- m_APInt(MulAP)))) {
+ match(&I, m_Mul(m_Exact(m_Shr(m_Value(NewOp), m_APInt(ShiftC)),
+ m_APInt(MulAP))))) {
if (BitWidth > 2 && (*MulAP - 1).isPowerOf2() &&
ShiftC == MulAP->logBase2()) {
BinaryOperator *OpBO = cast<BinaryOperator>(Op0);
- if (OpBO->isExact()) {
- Value *BinOp = Op0;
- if (HasNUW && OpBO->getOpcode() == Instruction::AShr &&
- OpBO->hasOneUse())
- BinOp = Builder.CreateLShr(
- NewOp, ConstantInt::get(Ty, ShiftC), "",
- /*isExact=*/true);
-
- auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp);
- if (HasNSW && (OpBO->getOpcode() == Instruction::LShr ||
- ShiftC->getZExtValue() < BitWidth - 1))
- NewAdd->setHasNoSignedWrap(true);
-
- NewAdd->setHasNoUnsignedWrap(HasNUW);
- return NewAdd;
- }
+ Value *BinOp = Op0;
+ if (HasNUW && OpBO->getOpcode() == Instruction::AShr &&
+ OpBO->hasOneUse())
+ BinOp = Builder.CreateLShr(
+ NewOp, ConstantInt::get(Ty, ShiftC), "",
+ /*isExact=*/true);
+
+ auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp);
+ if (HasNSW && (OpBO->getOpcode() == Instruction::LShr ||
+ ShiftC->getZExtValue() < BitWidth - 1))
+ NewAdd->setHasNoSignedWrap(true);
+
+ NewAdd->setHasNoUnsignedWrap(HasNUW);
+ return NewAdd;
}
}
}
>From 6daffddf6d0779686ed4d51466ebac0a3945e9df Mon Sep 17 00:00:00 2001
From: AtariDreams <gfunni234 at gmail.com>
Date: Thu, 20 Jun 2024 12:09:34 -0400
Subject: [PATCH 7/7] Update InstCombineMulDivRem.cpp
---
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 2e8d082e52e11..45d60f454278b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -264,7 +264,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
match(&I, m_Mul(m_Exact(m_Shr(m_Value(NewOp), m_APInt(ShiftC)),
m_APInt(MulAP))))) {
if (BitWidth > 2 && (*MulAP - 1).isPowerOf2() &&
- ShiftC == MulAP->logBase2()) {
+ *ShiftC == MulAP->logBase2()) {
BinaryOperator *OpBO = cast<BinaryOperator>(Op0);
Value *BinOp = Op0;
if (HasNUW && OpBO->getOpcode() == Instruction::AShr &&
More information about the llvm-commits
mailing list