mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-18 06:38:41 +00:00
Reorders two transforms that collide with each other
One performs: (X == 13 | X == 14) -> X-13 <u 2 The other: (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1 The problem is that there are certain values of C1 and C2 that trigger both transforms but the first one blocks out the second, this generates suboptimal code. Reordering the transforms should be better in every case and allows us to do interesting stuff like turn: %shr = lshr i32 %X, 4 %and = and i32 %shr, 15 %add = add i32 %and, -14 %tobool = icmp ne i32 %add, 0 into: %and = and i32 %X, 240 %tobool = icmp ne i32 %and, 224 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179493 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
687a9dfcb9
commit
024d943bca
@ -1547,14 +1547,6 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
|
||||
switch (RHSCC) {
|
||||
default: llvm_unreachable("Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
if (LHSCst == SubOne(RHSCst)) {
|
||||
// (X == 13 | X == 14) -> X-13 <u 2
|
||||
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
||||
Value *Add = Builder->CreateAdd(Val, AddCST, Val->getName()+".off");
|
||||
AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
|
||||
return Builder->CreateICmpULT(Add, AddCST);
|
||||
}
|
||||
|
||||
if (LHS->getOperand(0) == RHS->getOperand(0)) {
|
||||
// if LHSCst and RHSCst differ only by one bit:
|
||||
// (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1
|
||||
@ -1568,6 +1560,14 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
|
||||
}
|
||||
}
|
||||
|
||||
if (LHSCst == SubOne(RHSCst)) {
|
||||
// (X == 13 | X == 14) -> X-13 <u 2
|
||||
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
||||
Value *Add = Builder->CreateAdd(Val, AddCST, Val->getName()+".off");
|
||||
AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
|
||||
return Builder->CreateICmpULT(Add, AddCST);
|
||||
}
|
||||
|
||||
break; // (X == 13 | X == 15) -> no change
|
||||
case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change
|
||||
case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change
|
||||
|
@ -964,3 +964,15 @@ define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
|
||||
%cmp = icmp eq i32 %and, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK: @icmp_add_and_shr_ne_0
|
||||
; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, 240
|
||||
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[AND]], 224
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
define i1 @icmp_add_and_shr_ne_0(i32 %X) {
|
||||
%shr = lshr i32 %X, 4
|
||||
%and = and i32 %shr, 15
|
||||
%add = add i32 %and, -14
|
||||
%tobool = icmp ne i32 %add, 0
|
||||
ret i1 %tobool
|
||||
}
|
||||
|
@ -100,8 +100,8 @@ define i1 @test8(i32 %X) {
|
||||
%S = icmp eq i16 %R, 0
|
||||
ret i1 %S
|
||||
; CHECK: @test8
|
||||
; CHECK-NEXT: add i32 %X, -8
|
||||
; CHECK-NEXT: icmp ult i32 {{.*}}, 2
|
||||
; CHECK-NEXT: and i32 %X, -2
|
||||
; CHECK-NEXT: icmp eq i32 {{.*}}, 8
|
||||
; CHECK-NEXT: ret i1
|
||||
}
|
||||
|
||||
|
@ -178,12 +178,12 @@ define i1 @test18(i32 %A) {
|
||||
define i1 @test19(i32 %A) {
|
||||
%B = icmp eq i32 %A, 50
|
||||
%C = icmp eq i32 %A, 51
|
||||
;; (A-50) < 2
|
||||
;; (A&-2) == 50
|
||||
%D = or i1 %B, %C
|
||||
ret i1 %D
|
||||
; CHECK: @test19
|
||||
; CHECK: add i32
|
||||
; CHECK: icmp ult
|
||||
; CHECK: and i32
|
||||
; CHECK: icmp eq
|
||||
; CHECK: ret i1
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user