mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
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 llvm-svn: 279141
This commit is contained in:
parent
f315654cc5
commit
c5f63d0dfc
@ -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:
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user