diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4988,7 +4988,7 @@ return foldICmpWithZextOrSext(ICmp); } -static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS) { +static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned) { switch (BinaryOp) { default: llvm_unreachable("Unsupported binary op"); @@ -4996,7 +4996,8 @@ case Instruction::Sub: return match(RHS, m_Zero()); case Instruction::Mul: - return match(RHS, m_One()); + return !(RHS->getType()->isIntegerTy(1) && IsSigned) && + match(RHS, m_One()); } } @@ -5043,7 +5044,7 @@ if (auto *LHSTy = dyn_cast(LHS->getType())) OverflowTy = VectorType::get(OverflowTy, LHSTy->getElementCount()); - if (isNeutralValue(BinaryOp, RHS)) { + if (isNeutralValue(BinaryOp, RHS, IsSigned)) { Result = LHS; Overflow = ConstantInt::getFalse(OverflowTy); return true; diff --git a/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll --- a/llvm/test/Transforms/InstCombine/mul.ll +++ b/llvm/test/Transforms/InstCombine/mul.ll @@ -1761,3 +1761,24 @@ %r = mul i32 %zx, -16777216 ; -1 << 24 ret i32 %r } + +declare { i1, i1 } @llvm.smul.with.overflow.i1(i1, i1) +declare { i1, i1 } @llvm.umul.with.overflow.i1(i1, i1) + +define i1 @smul_i1_one(i1 %A) { +; CHECK-LABEL: @smul_i1_one( +; CHECK-NEXT: ret i1 [[A:%.*]] +; + %C = call {i1, i1} @llvm.smul.with.overflow.i1(i1 %A, i1 1) + %D = extractvalue {i1, i1} %C, 1 + ret i1 %D +} + +define i1 @umul_i1_one(i1 %A) { +; CHECK-LABEL: @umul_i1_one( +; CHECK-NEXT: ret i1 false +; + %C = call {i1, i1} @llvm.umul.with.overflow.i1(i1 %A, i1 1) + %D = extractvalue {i1, i1} %C, 1 + ret i1 %D +}