Make cltz and cttz zero undef when the operand cannot be zero in InstCombine

Summary: Also add popcount(n) == bitsize(n)  -> n == -1 transformation.

Reviewers: majnemer, spatel

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D23134

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279141 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Amaury Sechet 2016-08-18 20:43:50 +00:00
parent d87f299ea2
commit c43ec38718
2 changed files with 40 additions and 5 deletions

View File

@ -1133,7 +1133,10 @@ static Instruction *simplifyMaskedScatter(IntrinsicInst &II, InstCombiner &IC) {
return nullptr;
}
static Value *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
static Instruction *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<IntegerType>(Op0->getType());
@ -1156,8 +1159,20 @@ static Value *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
// zero, this value is constant.
// FIXME: This should be in InstSimplify because we're replacing an
// instruction with a constant.
if ((Mask & KnownZero) == Mask)
return ConstantInt::get(IT, APInt(BitWidth, NumMaskBits));
if ((Mask & KnownZero) == Mask) {
auto *C = ConstantInt::get(IT, APInt(BitWidth, NumMaskBits));
return IC.replaceInstUsesWith(II, C);
}
// If the input to cttz/ctlz is known to be non-zero,
// then change the 'ZeroIsUndef' parameter to 'true'
// because we know the zero behavior can't affect the result.
if (KnownOne != 0 || isKnownNonZero(Op0, IC.getDataLayout())) {
if (!match(II.getArgOperand(1), m_One())) {
II.setOperand(1, IC.Builder->getTrue());
return &II;
}
}
return nullptr;
}
@ -1457,8 +1472,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
case Intrinsic::cttz:
case Intrinsic::ctlz:
if (Value *V = foldCttzCtlz(*II, *this))
return replaceInstUsesWith(*II, V);
if (auto *I = foldCttzCtlz(*II, *this))
return I;
break;
case Intrinsic::uadd_with_overflow:

View File

@ -380,6 +380,16 @@ define i32 @ctlz_undef(i32 %Value) nounwind {
}
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_undef(i32 %Value) nounwind {
}
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)