Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1105,6 +1105,9 @@ } static Value *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) { + assert((II.getIntrinsicID() == Intrinsic::cttz || + II.getIntrinsicID() == Intrinsic::ctlz) && + "Expected cttz or ctlz intrinsic"); Value *Op0 = II.getArgOperand(0); // FIXME: Try to simplify vectors of integers. auto *IT = dyn_cast(Op0->getType()); @@ -1130,6 +1133,17 @@ if ((Mask & KnownZero) == Mask) return ConstantInt::get(IT, APInt(BitWidth, NumMaskBits)); + if (KnownOne != 0 || isKnownNonZero(Op0, IC.getDataLayout())) { + bool IsZeroUndef = false; + Value *Op1 = II.getArgOperand(1); + if (auto *Op1C = dyn_cast(Op1)) + IsZeroUndef = Op1C->getZExtValue() != 0; + if (!IsZeroUndef) { + IC.Worklist.Add(&II); + II.setOperand(1, ConstantInt::getAllOnesValue(Op1->getType())); + } + } + return nullptr; } Index: test/Transforms/InstCombine/intrinsics.ll =================================================================== --- test/Transforms/InstCombine/intrinsics.ll +++ test/Transforms/InstCombine/intrinsics.ll @@ -380,6 +380,16 @@ } +define i32 @ctlz_make_undef(i32 %a) { + %or = or i32 %a, 8 + %ctlz = tail call i32 @llvm.ctlz.i32(i32 %or, i1 false) + ret i32 %ctlz +; CHECK-LABEL: @ctlz_make_undef( +; CHECK-NEXT: %or = or i32 %a, 8 +; CHECK-NEXT: %ctlz = tail call i32 @llvm.ctlz.i32(i32 %or, i1 true) +; CHECK-NEXT: ret i32 %ctlz +} + define i32 @cttz_undef(i32 %Value) nounwind { ; CHECK-LABEL: @cttz_undef( ; CHECK-NEXT: ret i32 undef @@ -389,6 +399,16 @@ } +define i32 @cttz_make_undef(i32 %a) { + %or = or i32 %a, 8 + %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 false) + ret i32 %cttz +; CHECK-LABEL: @cttz_make_undef( +; CHECK-NEXT: %or = or i32 %a, 8 +; CHECK-NEXT: %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 true) +; CHECK-NEXT: ret i32 %cttz +} + define i32 @ctlz_select(i32 %Value) nounwind { ; CHECK-LABEL: @ctlz_select( ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 %Value, i1 false)