Skip to content

Commit

Permalink
[InstCombine] Optimize x * !x to 0 for vector llvm#84608
Browse files Browse the repository at this point in the history
  • Loading branch information
SahilPatidar committed Mar 12, 2024
1 parent 6e27dd4 commit a2890b7
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 35 deletions.
14 changes: 14 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,20 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
if (SimplifyAssociativeOrCommutative(I))
return &I;

// mul (sext X)), Y -> select X, -Y, 0
// mul Y, (sext X)) -> select X, -Y, 0
Value *SExtOp;
if (match(Op0, m_SExt(m_Value(SExtOp))) &&
SExtOp->getType()->isIntOrIntVectorTy(1)) {
return SelectInst::Create(SExtOp, Builder.CreateNeg(Op1),
ConstantInt::getNullValue(Op1->getType()));
}
if (match(Op1, m_SExt(m_Value(SExtOp))) &&
SExtOp->getType()->isIntOrIntVectorTy(1)) {
return SelectInst::Create(SExtOp, Builder.CreateNeg(Op0),
ConstantInt::getNullValue(Op0->getType()));
}

if (Instruction *X = foldVectorBinop(I))
return X;

Expand Down
30 changes: 16 additions & 14 deletions llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ define i32 @mul_bools_use3(i1 %x, i1 %y) {

define <3 x i32> @mul_bools_sext(<3 x i1> %x, <3 x i1> %y) {
; CHECK-LABEL: @mul_bools_sext(
; CHECK-NEXT: [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i32>
; CHECK-NEXT: [[NARROW:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> [[Y:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[R:%.*]] = zext <3 x i1> [[NARROW]] to <3 x i32>
; CHECK-NEXT: ret <3 x i32> [[R]]
;
%sx = sext <3 x i1> %x to <3 x i32>
Expand All @@ -204,8 +204,8 @@ define i32 @mul_bools_sext_use1(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_sext_use1(
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = zext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X:%.*]], i1 [[Y]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -219,8 +219,8 @@ define i32 @mul_bools_sext_use2(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_sext_use2(
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = zext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[Y]], i1 [[X:%.*]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -236,7 +236,8 @@ define i32 @mul_bools_sext_use3(i1 %x, i1 %y) {
; CHECK-NEXT: call void @use32(i32 [[SX]])
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[R:%.*]] = mul nsw i32 [[SY]], [[SX]]
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[Y]], i1 [[X]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -249,8 +250,8 @@ define i32 @mul_bools_sext_use3(i1 %x, i1 %y) {

define <3 x i32> @mul_bools_mixed_ext(<3 x i1> %x, <3 x i1> %y) {
; CHECK-LABEL: @mul_bools_mixed_ext(
; CHECK-NEXT: [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = sext <3 x i1> [[MULBOOL]] to <3 x i32>
; CHECK-NEXT: [[NARROW:%.*]] = select <3 x i1> [[Y:%.*]], <3 x i1> [[X:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[R:%.*]] = sext <3 x i1> [[NARROW]] to <3 x i32>
; CHECK-NEXT: ret <3 x i32> [[R]]
;
%zx = zext <3 x i1> %x to <3 x i32>
Expand All @@ -263,8 +264,8 @@ define i32 @mul_bools_mixed_ext_use1(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_mixed_ext_use1(
; CHECK-NEXT: [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[ZY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = sext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X:%.*]], i1 [[Y]], i1 false
; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -278,8 +279,8 @@ define i32 @mul_bools_mixed_ext_use2(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_mixed_ext_use2(
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = sext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[Y]], i1 [[X:%.*]], i1 false
; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%zx = zext i1 %x to i32
Expand All @@ -295,7 +296,8 @@ define i32 @mul_bools_mixed_ext_use3(i1 %x, i1 %y) {
; CHECK-NEXT: call void @use32(i32 [[SX]])
; CHECK-NEXT: [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[ZY]])
; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 [[SX]], i32 0
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X]], i1 [[Y]], i1 false
; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand Down
44 changes: 28 additions & 16 deletions llvm/test/Transforms/InstCombine/mul.ll
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ define i32 @mul_bools_use3(i1 %x, i1 %y) {

define <3 x i32> @mul_bools_sext(<3 x i1> %x, <3 x i1> %y) {
; CHECK-LABEL: @mul_bools_sext(
; CHECK-NEXT: [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i32>
; CHECK-NEXT: [[NARROW:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> [[Y:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[R:%.*]] = zext <3 x i1> [[NARROW]] to <3 x i32>
; CHECK-NEXT: ret <3 x i32> [[R]]
;
%sx = sext <3 x i1> %x to <3 x i32>
Expand All @@ -457,8 +457,8 @@ define i32 @mul_bools_sext_use1(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_sext_use1(
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = zext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X:%.*]], i1 [[Y]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -472,8 +472,8 @@ define i32 @mul_bools_sext_use2(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_sext_use2(
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = zext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[Y]], i1 [[X:%.*]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -489,7 +489,8 @@ define i32 @mul_bools_sext_use3(i1 %x, i1 %y) {
; CHECK-NEXT: call void @use32(i32 [[SX]])
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[R:%.*]] = mul nsw i32 [[SY]], [[SX]]
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[Y]], i1 [[X]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -502,8 +503,8 @@ define i32 @mul_bools_sext_use3(i1 %x, i1 %y) {

define i32 @mul_bools_sext_one_use_per_op(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_sext_one_use_per_op(
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = zext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
; CHECK-NEXT: [[R:%.*]] = zext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand Down Expand Up @@ -572,8 +573,8 @@ define i32 @mul_bool_zext_one_extra_user(i1 %x) {

define <3 x i32> @mul_bools_mixed_ext(<3 x i1> %x, <3 x i1> %y) {
; CHECK-LABEL: @mul_bools_mixed_ext(
; CHECK-NEXT: [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = sext <3 x i1> [[MULBOOL]] to <3 x i32>
; CHECK-NEXT: [[NARROW:%.*]] = select <3 x i1> [[Y:%.*]], <3 x i1> [[X:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[R:%.*]] = sext <3 x i1> [[NARROW]] to <3 x i32>
; CHECK-NEXT: ret <3 x i32> [[R]]
;
%zx = zext <3 x i1> %x to <3 x i32>
Expand All @@ -586,8 +587,8 @@ define i32 @mul_bools_mixed_ext_use1(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_mixed_ext_use1(
; CHECK-NEXT: [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[ZY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = sext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X:%.*]], i1 [[Y]], i1 false
; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand All @@ -601,8 +602,8 @@ define i32 @mul_bools_mixed_ext_use2(i1 %x, i1 %y) {
; CHECK-LABEL: @mul_bools_mixed_ext_use2(
; CHECK-NEXT: [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[SY]])
; CHECK-NEXT: [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = sext i1 [[MULBOOL]] to i32
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[Y]], i1 [[X:%.*]], i1 false
; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%zx = zext i1 %x to i32
Expand All @@ -618,7 +619,8 @@ define i32 @mul_bools_mixed_ext_use3(i1 %x, i1 %y) {
; CHECK-NEXT: call void @use32(i32 [[SX]])
; CHECK-NEXT: [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use32(i32 [[ZY]])
; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 [[SX]], i32 0
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[X]], i1 [[Y]], i1 false
; CHECK-NEXT: [[R:%.*]] = sext i1 [[NARROW]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sx = sext i1 %x to i32
Expand Down Expand Up @@ -2049,3 +2051,13 @@ define i32 @zext_negpow2_use(i8 %x) {
%r = mul i32 %zx, -16777216 ; -1 << 24
ret i32 %r
}

define i32 @mul_icmp_with_zero(i32 %x) {
; CHECK-LABEL: @mul_icmp_with_zero(
; CHECK-NEXT: ret i32 0
;
%cmp = icmp eq i32 %x, zeroinitializer
%sext = sext i1 %cmp to i32
%mul = mul i32 %sext, %x
ret i32 %mul
}
8 changes: 3 additions & 5 deletions llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,9 @@ define i64 @sext_diff_i1_xor_sub_1(i64 %a, i1 %b, i1 %c) {
define i64 @sext_multi_uses(i64 %a, i1 %b, i64 %x) {
; CHECK-LABEL: define i64 @sext_multi_uses(
; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]], i64 [[X:%.*]]) {
; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[A]]
; CHECK-NEXT: [[E:%.*]] = select i1 [[B]], i64 [[TMP1]], i64 [[A]]
; CHECK-NEXT: [[F:%.*]] = mul i64 [[C]], [[X]]
; CHECK-NEXT: [[R:%.*]] = add i64 [[F]], [[E]]
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X]], [[A]]
; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[TMP1]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i64 [[TMP2]], i64 [[A]]
; CHECK-NEXT: ret i64 [[R]]
;
%c = sext i1 %b to i64
Expand Down

0 comments on commit a2890b7

Please sign in to comment.