[llvm] d30cf77 - [InstCombine] complete fold extractvalue (any_mul_with_overflow X, -1)
Chenbing Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 1 20:00:57 PDT 2022
Author: Chenbing Zheng
Date: 2022-09-02T10:58:42+08:00
New Revision: d30cf77cb1e4f743c52adbd52bf4f079794eded3
URL: https://github.com/llvm/llvm-project/commit/d30cf77cb1e4f743c52adbd52bf4f079794eded3
DIFF: https://github.com/llvm/llvm-project/commit/d30cf77cb1e4f743c52adbd52bf4f079794eded3.diff
LOG: [InstCombine] complete fold extractvalue (any_mul_with_overflow X, -1)
When we do extractvalue (any_mul_with_overflow X, -1) --> (-X and icmp),
which left partly failed to match vector constant with poison element.
This patch try to fix it.
Alive2: https://alive2.llvm.org/ce/z/2rGp_3
Reviewed By: spatel
Differential Revision: https://reviews.llvm.org/D132996
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/with_overflow.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index e673593028680..8dc89b57f51fa 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3256,11 +3256,14 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
// extractvalue (any_mul_with_overflow X, -1), 0 --> -X
Intrinsic::ID OvID = WO->getIntrinsicID();
- if (*EV.idx_begin() == 0 &&
- (OvID == Intrinsic::smul_with_overflow ||
- OvID == Intrinsic::umul_with_overflow) &&
- match(WO->getArgOperand(1), m_AllOnes())) {
- return BinaryOperator::CreateNeg(WO->getArgOperand(0));
+ const APInt *C = nullptr;
+ if (match(WO->getRHS(), m_APIntAllowUndef(C))) {
+ if (*EV.idx_begin() == 0 &&
+ (OvID == Intrinsic::smul_with_overflow ||
+ OvID == Intrinsic::umul_with_overflow) &&
+ C->isAllOnes()) {
+ return BinaryOperator::CreateNeg(WO->getArgOperand(0));
+ }
}
// We're extracting from an overflow intrinsic. See if we're the only user.
@@ -3289,8 +3292,7 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
// If only the overflow result is used, and the right hand side is a
// constant (or constant splat), we can remove the intrinsic by directly
// checking for overflow.
- const APInt *C;
- if (match(WO->getRHS(), m_APInt(C))) {
+ if (C) {
// Compute the no-wrap range for LHS given RHS=C, then construct an
// equivalent icmp, potentially using an offset.
ConstantRange NWR = ConstantRange::makeExactNoWrapRegion(
diff --git a/llvm/test/Transforms/InstCombine/with_overflow.ll b/llvm/test/Transforms/InstCombine/with_overflow.ll
index b692530554556..fc8944e90f8c9 100644
--- a/llvm/test/Transforms/InstCombine/with_overflow.ll
+++ b/llvm/test/Transforms/InstCombine/with_overflow.ll
@@ -793,13 +793,10 @@ define <4 x i8> @smul_neg1_vec(<4 x i8> %x, <4 x i1>* %p) {
ret <4 x i8> %r
}
-; TODO: partly failed to match vector constant with poison element
-
define <4 x i8> @smul_neg1_vec_poison(<4 x i8> %x, <4 x i1>* %p) {
; CHECK-LABEL: @smul_neg1_vec_poison(
-; CHECK-NEXT: [[M:%.*]] = tail call { <4 x i8>, <4 x i1> } @llvm.smul.with.overflow.v4i8(<4 x i8> [[X:%.*]], <4 x i8> <i8 -1, i8 -1, i8 poison, i8 -1>)
-; CHECK-NEXT: [[R:%.*]] = sub <4 x i8> zeroinitializer, [[X]]
-; CHECK-NEXT: [[OV:%.*]] = extractvalue { <4 x i8>, <4 x i1> } [[M]], 1
+; CHECK-NEXT: [[R:%.*]] = sub <4 x i8> zeroinitializer, [[X:%.*]]
+; CHECK-NEXT: [[OV:%.*]] = icmp eq <4 x i8> [[X]], <i8 -128, i8 -128, i8 -128, i8 -128>
; CHECK-NEXT: store <4 x i1> [[OV]], <4 x i1>* [[P:%.*]], align 1
; CHECK-NEXT: ret <4 x i8> [[R]]
;
@@ -853,13 +850,10 @@ define <4 x i8> @umul_neg1_vec(<4 x i8> %x, <4 x i1>* %p) {
ret <4 x i8> %r
}
-; TODO: partly failed to match vector constant with poison element
-
define <4 x i8> @umul_neg1_vec_poison(<4 x i8> %x, <4 x i1>* %p) {
; CHECK-LABEL: @umul_neg1_vec_poison(
-; CHECK-NEXT: [[M:%.*]] = tail call { <4 x i8>, <4 x i1> } @llvm.umul.with.overflow.v4i8(<4 x i8> [[X:%.*]], <4 x i8> <i8 poison, i8 -1, i8 -1, i8 poison>)
-; CHECK-NEXT: [[R:%.*]] = sub <4 x i8> zeroinitializer, [[X]]
-; CHECK-NEXT: [[OV:%.*]] = extractvalue { <4 x i8>, <4 x i1> } [[M]], 1
+; CHECK-NEXT: [[R:%.*]] = sub <4 x i8> zeroinitializer, [[X:%.*]]
+; CHECK-NEXT: [[OV:%.*]] = icmp ugt <4 x i8> [[X]], <i8 1, i8 1, i8 1, i8 1>
; CHECK-NEXT: store <4 x i1> [[OV]], <4 x i1>* [[P:%.*]], align 1
; CHECK-NEXT: ret <4 x i8> [[R]]
;
@@ -870,6 +864,17 @@ define <4 x i8> @umul_neg1_vec_poison(<4 x i8> %x, <4 x i1>* %p) {
ret <4 x i8> %r
}
+define <4 x i1> @smul_not_neg1_vec(<4 x i8> %x) {
+; CHECK-LABEL: @smul_not_neg1_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i8> [[X:%.*]], <i8 -43, i8 -43, i8 -43, i8 -43>
+; CHECK-NEXT: [[OV:%.*]] = icmp ult <4 x i8> [[TMP1]], <i8 -85, i8 -85, i8 -85, i8 -85>
+; CHECK-NEXT: ret <4 x i1> [[OV]]
+;
+ %m = call { <4 x i8>, <4 x i1> } @llvm.smul.with.overflow.v4i8(<4 x i8> %x, <4 x i8> <i8 -3, i8 -3, i8 poison, i8 -3>)
+ %ov = extractvalue { <4 x i8>, <4 x i1> } %m, 1
+ ret <4 x i1> %ov
+}
+
; TODO: this could be 'shl' and 'icmp'
define i8 @umul_2(i8 %x, i1* %p) {
More information about the llvm-commits
mailing list