Skip to content

Commit

Permalink
[InstCombine] reduce smul.ov with i1 types to 'and'
Browse files Browse the repository at this point in the history
https://alive2.llvm.org/ce/z/5tLkW6

There's still a miscompile bug as shown in issue #59876 / D141214 .
  • Loading branch information
rotateright committed Jan 9, 2023
1 parent fc9d54a commit 2dcbd74
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/Transforms/InstCombine/smulo.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 2dcbd74

Please sign in to comment.