mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
optimize comparisons against cttz/ctlz/ctpop, patch by Alastair Lynn!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92745 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
aceba31b7a
commit
033574074d
@ -1418,11 +1418,33 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
}
|
||||
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(LHSI)) {
|
||||
// Handle icmp {eq|ne} <intrinsic>, intcst.
|
||||
if (II->getIntrinsicID() == Intrinsic::bswap) {
|
||||
switch (II->getIntrinsicID()) {
|
||||
case Intrinsic::bswap:
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getOperand(1));
|
||||
ICI.setOperand(1, ConstantInt::get(II->getContext(), RHSV.byteSwap()));
|
||||
return &ICI;
|
||||
case Intrinsic::ctlz:
|
||||
case Intrinsic::cttz:
|
||||
// ctz(A) == bitwidth(a) -> A == 0 and likewise for !=
|
||||
if (RHSV == RHS->getType()->getBitWidth()) {
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getOperand(1));
|
||||
ICI.setOperand(1, ConstantInt::get(RHS->getType(), 0));
|
||||
return &ICI;
|
||||
}
|
||||
break;
|
||||
case Intrinsic::ctpop:
|
||||
// popcount(A) == 0 -> A == 0 and likewise for !=
|
||||
if (RHS->isZero()) {
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getOperand(1));
|
||||
ICI.setOperand(1, RHS);
|
||||
return &ICI;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
|
||||
declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
|
||||
declare double @llvm.powi.f64(double, i32) nounwind readonly
|
||||
declare i32 @llvm.cttz.i32(i32) nounwind readnone
|
||||
declare i32 @llvm.ctlz.i32(i32) nounwind readnone
|
||||
declare i32 @llvm.ctpop.i32(i32) nounwind readnone
|
||||
declare i8 @llvm.ctlz.i8(i8) nounwind readnone
|
||||
|
||||
define i8 @test1(i8 %A, i8 %B) {
|
||||
@ -99,8 +101,7 @@ entry:
|
||||
; CHECK: volatile store double %V
|
||||
}
|
||||
|
||||
define i32 @cttz(i32 %a)
|
||||
{
|
||||
define i32 @cttz(i32 %a) {
|
||||
entry:
|
||||
%or = or i32 %a, 8
|
||||
%and = and i32 %or, -8
|
||||
@ -111,8 +112,7 @@ entry:
|
||||
; CHECK-NEXT: ret i32 3
|
||||
}
|
||||
|
||||
define i8 @ctlz(i8 %a)
|
||||
{
|
||||
define i8 @ctlz(i8 %a) {
|
||||
entry:
|
||||
%or = or i8 %a, 32
|
||||
%and = and i8 %or, 63
|
||||
@ -122,3 +122,25 @@ entry:
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret i8 2
|
||||
}
|
||||
|
||||
define void @cmp.simplify(i32 %a, i32 %b, i1* %c) {
|
||||
entry:
|
||||
%lz = tail call i32 @llvm.ctlz.i32(i32 %a) nounwind readnone
|
||||
%lz.cmp = icmp eq i32 %lz, 32
|
||||
volatile store i1 %lz.cmp, i1* %c
|
||||
%tz = tail call i32 @llvm.cttz.i32(i32 %a) nounwind readnone
|
||||
%tz.cmp = icmp ne i32 %tz, 32
|
||||
volatile store i1 %tz.cmp, i1* %c
|
||||
%pop = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone
|
||||
%pop.cmp = icmp eq i32 %pop, 0
|
||||
volatile store i1 %pop.cmp, i1* %c
|
||||
ret void
|
||||
; CHECK: @cmp.simplify
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: %lz.cmp = icmp eq i32 %a, 0
|
||||
; CHECK-NEXT: volatile store i1 %lz.cmp, i1* %c
|
||||
; CHECK-NEXT: %tz.cmp = icmp ne i32 %a, 0
|
||||
; CHECK-NEXT: volatile store i1 %tz.cmp, i1* %c
|
||||
; CHECK-NEXT: %pop.cmp = icmp eq i32 %b, 0
|
||||
; CHECK-NEXT: volatile store i1 %pop.cmp, i1* %c
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user