mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Implement rdar://6480391, extending of equality icmp's to avoid a truncation.
I noticed this in the code compiled for a routine using std::map, which produced this code: %25 = tail call i32 @memcmp(i8* %24, i8* %23, i32 6) nounwind readonly %.lobit.i = lshr i32 %25, 31 ; <i32> [#uses=1] %tmp.i = trunc i32 %.lobit.i to i8 ; <i8> [#uses=1] %toBool = icmp eq i8 %tmp.i, 0 ; <i1> [#uses=1] br i1 %toBool, label %bb3, label %bb4 which compiled to: call L_memcmp$stub shrl $31, %eax testb %al, %al jne LBB1_11 ## with this change, we compile it to: call L_memcmp$stub testl %eax, %eax js LBB1_11 This triggers all the time in common code, with patters like this: %169 = and i32 %ply, 1 ; <i32> [#uses=1] %170 = trunc i32 %169 to i8 ; <i8> [#uses=1] %toBool = icmp ne i8 %170, 0 ; <i1> [#uses=1] %7 = lshr i32 %6, 24 ; <i32> [#uses=1] %9 = trunc i32 %7 to i8 ; <i8> [#uses=1] %10 = icmp ne i8 %9, 0 ; <i1> [#uses=1] etc git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61985 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6d6b410698
commit
a80d668215
@ -6343,6 +6343,28 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
const APInt &RHSV = RHS->getValue();
|
||||
|
||||
switch (LHSI->getOpcode()) {
|
||||
case Instruction::Trunc:
|
||||
if (ICI.isEquality() && LHSI->hasOneUse()) {
|
||||
// Simplify icmp eq (trunc x to i8), 42 -> icmp eq x, 42|highbits if all
|
||||
// of the high bits truncated out of x are known.
|
||||
unsigned DstBits = LHSI->getType()->getPrimitiveSizeInBits(),
|
||||
SrcBits = LHSI->getOperand(0)->getType()->getPrimitiveSizeInBits();
|
||||
APInt Mask(APInt::getHighBitsSet(SrcBits, SrcBits-DstBits));
|
||||
APInt KnownZero(SrcBits, 0), KnownOne(SrcBits, 0);
|
||||
ComputeMaskedBits(LHSI->getOperand(0), Mask, KnownZero, KnownOne);
|
||||
|
||||
// If all the high bits are known, we can do this xform.
|
||||
if ((KnownZero|KnownOne).countLeadingOnes() >= SrcBits-DstBits) {
|
||||
// Pull in the high bits from known-ones set.
|
||||
APInt NewRHS(RHS->getValue());
|
||||
NewRHS.zext(SrcBits);
|
||||
NewRHS |= KnownOne;
|
||||
return new ICmpInst(ICI.getPredicate(), LHSI->getOperand(0),
|
||||
ConstantInt::get(NewRHS));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Instruction::Xor: // (icmp pred (xor X, XorCST), CI)
|
||||
if (ConstantInt *XorCST = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
|
||||
// If this is a comparison that tests the signbit (X < 0) or (x > -1),
|
||||
|
@ -1,7 +1,5 @@
|
||||
; Tests to make sure elimination of casts is working correctly
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
|
||||
; RUN: grep %c | notcast
|
||||
; END.
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep %c | notcast
|
||||
|
||||
@inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1]
|
||||
|
||||
@ -238,3 +236,21 @@ define i16 @test35(i16 %a) {
|
||||
ret i16 %c2
|
||||
}
|
||||
|
||||
; icmp sgt i32 %a, -1
|
||||
; rdar://6480391
|
||||
define i1 @test36(i32 %a) {
|
||||
%b = lshr i32 %a, 31
|
||||
%c = trunc i32 %b to i8
|
||||
%d = icmp eq i8 %c, 0
|
||||
ret i1 %d
|
||||
}
|
||||
|
||||
; ret i1 false
|
||||
define i1 @test37(i32 %a) {
|
||||
%b = lshr i32 %a, 31
|
||||
%c = or i32 %b, 512
|
||||
%d = trunc i32 %c to i8
|
||||
%e = icmp eq i8 %d, 11
|
||||
ret i1 %e
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep icmp
|
||||
; END.
|
||||
|
||||
define i32 @test1(i32 %X) {
|
||||
entry:
|
||||
|
Loading…
Reference in New Issue
Block a user