[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