[llvm] 2dcbd74 - [InstCombine] reduce smul.ov with i1 types to 'and'
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 9 07:28:54 PST 2023
Author: Sanjay Patel
Date: 2023-01-09T10:27:15-05:00
New Revision: 2dcbd740eee0283e76d08a8b646a7b5a8fbf969c
URL: https://github.com/llvm/llvm-project/commit/2dcbd740eee0283e76d08a8b646a7b5a8fbf969c
DIFF: https://github.com/llvm/llvm-project/commit/2dcbd740eee0283e76d08a8b646a7b5a8fbf969c.diff
LOG: [InstCombine] reduce smul.ov with i1 types to 'and'
https://alive2.llvm.org/ce/z/5tLkW6
There's still a miscompile bug as shown in issue #59876 / D141214 .
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/smulo.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index df93d5a76692..48f00fac2d0d 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3316,6 +3316,12 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
if (OvID == Intrinsic::usub_with_overflow)
return new ICmpInst(ICmpInst::ICMP_ULT, WO->getLHS(), WO->getRHS());
+ // smul with i1 types overflows when both sides are set: -1 * -1 == +1, but
+ // +1 is not possible because we assume signed values.
+ if (OvID == Intrinsic::smul_with_overflow &&
+ WO->getLHS()->getType()->isIntOrIntVectorTy(1))
+ return BinaryOperator::CreateAnd(WO->getLHS(), WO->getRHS());
+
// 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.
diff --git a/llvm/test/Transforms/InstCombine/smulo.ll b/llvm/test/Transforms/InstCombine/smulo.ll
index 6f88e201fae9..8da1a5e2e707 100644
--- a/llvm/test/Transforms/InstCombine/smulo.ll
+++ b/llvm/test/Transforms/InstCombine/smulo.ll
@@ -140,8 +140,7 @@ define <2 x i1> @v2i1_res_by_one(<2 x i1> %x) {
define i1 @i1_ov(i1 %x, i1 %y) {
; CHECK-LABEL: @i1_ov(
-; CHECK-NEXT: [[M:%.*]] = call { i1, i1 } @llvm.smul.with.overflow.i1(i1 [[X:%.*]], i1 [[Y:%.*]])
-; CHECK-NEXT: [[OV:%.*]] = extractvalue { i1, i1 } [[M]], 1
+; CHECK-NEXT: [[OV:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[OV]]
;
%m = call {i1, i1} @llvm.smul.with.overflow.i1(i1 %x, i1 %y)
@@ -151,8 +150,7 @@ define i1 @i1_ov(i1 %x, i1 %y) {
define <2 x i1> @v2i1_ov(<2 x i1> %x, <2 x i1> %y) {
; CHECK-LABEL: @v2i1_ov(
-; CHECK-NEXT: [[M:%.*]] = call { <2 x i1>, <2 x i1> } @llvm.smul.with.overflow.v2i1(<2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]])
-; CHECK-NEXT: [[OV:%.*]] = extractvalue { <2 x i1>, <2 x i1> } [[M]], 1
+; CHECK-NEXT: [[OV:%.*]] = and <2 x i1> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[OV]]
;
%m = call {<2 x i1>, <2 x i1>} @llvm.smul.with.overflow.v2i1(<2 x i1> %x, <2 x i1> %y)
More information about the llvm-commits
mailing list