mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
Teach InstCombine to work with smaller legal types in icmp (shl %v, C1), C2
It enables to work with a smaller constant, which is target friendly for those which can compare to immediates. It also avoids inserting a shift in favor of a trunc, which can be free on some targets. This used to work until LLVM-3.1, but regressed with the 3.2 release. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175270 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
85d2760c8e
commit
7c5c9b39c9
@ -1331,6 +1331,25 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
|||||||
return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ,
|
return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ,
|
||||||
And, Constant::getNullValue(And->getType()));
|
And, Constant::getNullValue(And->getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform (icmp pred iM (shl iM %v, N), CI)
|
||||||
|
// -> (icmp pred i(M-N) (trunc %v iM to i(N-N)), (trunc (CI>>N))
|
||||||
|
// Transform the shl to a trunc if (trunc (CI>>N)) has no loss.
|
||||||
|
// This enables to get rid of the shift in favor of a trunc which can be
|
||||||
|
// free on the target. It has the additional benefit of comparing to a
|
||||||
|
// smaller constant, which will be target friendly.
|
||||||
|
unsigned Amt = ShAmt->getLimitedValue(TypeBits-1);
|
||||||
|
if (Amt != 0 && RHSV.countTrailingZeros() >= Amt) {
|
||||||
|
Type *NTy = IntegerType::get(ICI.getContext(), TypeBits - Amt);
|
||||||
|
Constant *NCI = ConstantExpr::getTrunc(
|
||||||
|
ConstantExpr::getAShr(RHS,
|
||||||
|
ConstantInt::get(RHS->getType(), Amt)),
|
||||||
|
NTy);
|
||||||
|
return new ICmpInst(ICI.getPredicate(),
|
||||||
|
Builder->CreateTrunc(LHSI->getOperand(0), NTy),
|
||||||
|
ConstantExpr::getTrunc(NCI, NTy));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,9 +99,9 @@ define i1 @ashr_icmp2(i64 %X) nounwind {
|
|||||||
; PR9998
|
; PR9998
|
||||||
; Make sure we don't transform the ashr here into an sdiv
|
; Make sure we don't transform the ashr here into an sdiv
|
||||||
; CHECK: @pr9998
|
; CHECK: @pr9998
|
||||||
; CHECK: = and i32 %V, 1
|
; CHECK: [[BIT:%[A-Za-z0-9.]+]] = and i32 %V, 1
|
||||||
; CHECK: %Z = icmp ne
|
; CHECK-NEXT: [[CMP:%[A-Za-z0-9.]+]] = icmp ne i32 [[BIT]], 0
|
||||||
; CHECK: ret i1 %Z
|
; CHECK-NEXT: ret i1 [[CMP]]
|
||||||
define i1 @pr9998(i32 %V) nounwind {
|
define i1 @pr9998(i32 %V) nounwind {
|
||||||
entry:
|
entry:
|
||||||
%W = shl i32 %V, 31
|
%W = shl i32 %V, 31
|
||||||
@ -112,6 +112,7 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; CHECK: @udiv_icmp1
|
; CHECK: @udiv_icmp1
|
||||||
; CHECK: icmp ne i64 %X, 0
|
; CHECK: icmp ne i64 %X, 0
|
||||||
define i1 @udiv_icmp1(i64 %X) nounwind {
|
define i1 @udiv_icmp1(i64 %X) nounwind {
|
||||||
|
@ -706,3 +706,41 @@ define i1 @test69(i32 %c) nounwind uwtable {
|
|||||||
%3 = or i1 %1, %2
|
%3 = or i1 %1, %2
|
||||||
ret i1 %3
|
ret i1 %3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK: @icmp_sext16trunc
|
||||||
|
; CHECK-NEXT: %1 = trunc i32 %x to i16
|
||||||
|
; CHECK-NEXT: %cmp = icmp slt i16 %1, 36
|
||||||
|
define i1 @icmp_sext16trunc(i32 %x) {
|
||||||
|
%trunc = trunc i32 %x to i16
|
||||||
|
%sext = sext i16 %trunc to i32
|
||||||
|
%cmp = icmp slt i32 %sext, 36
|
||||||
|
ret i1 %cmp
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: @icmp_sext8trunc
|
||||||
|
; CHECK-NEXT: %1 = trunc i32 %x to i8
|
||||||
|
; CHECK-NEXT: %cmp = icmp slt i8 %1, 36
|
||||||
|
define i1 @icmp_sext8trunc(i32 %x) {
|
||||||
|
%trunc = trunc i32 %x to i8
|
||||||
|
%sext = sext i8 %trunc to i32
|
||||||
|
%cmp = icmp slt i32 %sext, 36
|
||||||
|
ret i1 %cmp
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: @icmp_shl16
|
||||||
|
; CHECK-NEXT: %1 = trunc i32 %x to i16
|
||||||
|
; CHECK-NEXT: %cmp = icmp slt i16 %1, 36
|
||||||
|
define i1 @icmp_shl16(i32 %x) {
|
||||||
|
%shl = shl i32 %x, 16
|
||||||
|
%cmp = icmp slt i32 %shl, 2359296
|
||||||
|
ret i1 %cmp
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: @icmp_shl24
|
||||||
|
; CHECK-NEXT: %1 = trunc i32 %x to i8
|
||||||
|
; CHECK-NEXT: %cmp = icmp slt i8 %1, 36
|
||||||
|
define i1 @icmp_shl24(i32 %x) {
|
||||||
|
%shl = shl i32 %x, 24
|
||||||
|
%cmp = icmp slt i32 %shl, 603979776
|
||||||
|
ret i1 %cmp
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user