mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[AArch64][GlobalISel] Optimize compare and branch cases with G_INTTOPTR and unknown values.
Since we have distinct types for pointers and scalars, G_INTTOPTRs can sometimes obstruct attempts to find constant source values. These usually come about when try to do some kind of null pointer check. Teaching getConstantVRegValWithLookThrough about this operation allows the CBZ/CBNZ optimization to catch more cases. This change also improves the case where we can't find a constant source at all. Previously we would emit a cmp, cset and tbnz for that. Now we try to just emit a cmp and conditional branch, saving an instruction. The cumulative code size improvement of this change plus D64354 is 5.5% geomean on arm64 CTMark -O0. Differential Revision: https://reviews.llvm.org/D64377 llvm-svn: 365690
This commit is contained in:
parent
6a298ee9be
commit
eecd26ab7d
@ -238,6 +238,9 @@ Optional<ValueAndVReg> llvm::getConstantVRegValWithLookThrough(
|
||||
if (TargetRegisterInfo::isPhysicalRegister(VReg))
|
||||
return None;
|
||||
break;
|
||||
case TargetOpcode::G_INTTOPTR:
|
||||
VReg = MI->getOperand(1).getReg();
|
||||
break;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
|
@ -899,12 +899,23 @@ bool AArch64InstructionSelector::selectCompareBranch(
|
||||
|
||||
Register LHS = CCMI->getOperand(2).getReg();
|
||||
Register RHS = CCMI->getOperand(3).getReg();
|
||||
if (!getConstantVRegVal(RHS, MRI))
|
||||
auto VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI);
|
||||
if (!VRegAndVal)
|
||||
std::swap(RHS, LHS);
|
||||
|
||||
const auto RHSImm = getConstantVRegVal(RHS, MRI);
|
||||
if (!RHSImm || *RHSImm != 0)
|
||||
return false;
|
||||
VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI);
|
||||
if (!VRegAndVal || VRegAndVal->Value != 0) {
|
||||
MachineIRBuilder MIB(I);
|
||||
// If we can't select a CBZ then emit a cmp + Bcc.
|
||||
if (!emitIntegerCompare(CCMI->getOperand(2), CCMI->getOperand(3),
|
||||
CCMI->getOperand(1), MIB))
|
||||
return false;
|
||||
const AArch64CC::CondCode CC = changeICMPPredToAArch64CC(
|
||||
(CmpInst::Predicate)CCMI->getOperand(1).getPredicate());
|
||||
MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC).addMBB(DestMBB);
|
||||
I.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
|
||||
if (RB.getID() != AArch64::GPRRegBankID)
|
||||
|
@ -1,3 +1,4 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
# RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
|
||||
|
||||
--- |
|
||||
@ -5,20 +6,23 @@
|
||||
define void @cbz_s64() { ret void }
|
||||
define void @cbnz_s32() { ret void }
|
||||
define void @cbnz_s64() { ret void }
|
||||
define hidden void @test_rhs_inttoptr(i64* %p) { ret void }
|
||||
define hidden void @test_rhs_unknown(i64* %p) { ret void }
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: cbz_s32
|
||||
name: cbz_s32
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: bb.0:
|
||||
# CHECK: %0:gpr32 = COPY $w0
|
||||
# CHECK: CBZW %0, %bb.1
|
||||
# CHECK: B %bb.0
|
||||
body: |
|
||||
; CHECK-LABEL: name: cbz_s32
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
|
||||
; CHECK: CBZW [[COPY]], %bb.1
|
||||
; CHECK: B %bb.0
|
||||
; CHECK: bb.1:
|
||||
bb.0:
|
||||
liveins: $w0
|
||||
successors: %bb.0, %bb.1
|
||||
@ -34,17 +38,18 @@ body: |
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: cbz_s64
|
||||
name: cbz_s64
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: bb.0:
|
||||
# CHECK: %0:gpr64 = COPY $x0
|
||||
# CHECK: CBZX %0, %bb.1
|
||||
# CHECK: B %bb.0
|
||||
body: |
|
||||
; CHECK-LABEL: name: cbz_s64
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
|
||||
; CHECK: CBZX [[COPY]], %bb.1
|
||||
; CHECK: B %bb.0
|
||||
; CHECK: bb.1:
|
||||
bb.0:
|
||||
liveins: $x0
|
||||
successors: %bb.0, %bb.1
|
||||
@ -60,17 +65,18 @@ body: |
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: cbnz_s32
|
||||
name: cbnz_s32
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: bb.0:
|
||||
# CHECK: %0:gpr32 = COPY $w0
|
||||
# CHECK: CBNZW %0, %bb.1
|
||||
# CHECK: B %bb.0
|
||||
body: |
|
||||
; CHECK-LABEL: name: cbnz_s32
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
|
||||
; CHECK: CBNZW [[COPY]], %bb.1
|
||||
; CHECK: B %bb.0
|
||||
; CHECK: bb.1:
|
||||
bb.0:
|
||||
liveins: $w0
|
||||
successors: %bb.0, %bb.1
|
||||
@ -86,17 +92,18 @@ body: |
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: cbnz_s64
|
||||
name: cbnz_s64
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: bb.0:
|
||||
# CHECK: %0:gpr64 = COPY $x0
|
||||
# CHECK: CBNZX %0, %bb.1
|
||||
# CHECK: B %bb.0
|
||||
body: |
|
||||
; CHECK-LABEL: name: cbnz_s64
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
|
||||
; CHECK: CBNZX [[COPY]], %bb.1
|
||||
; CHECK: B %bb.0
|
||||
; CHECK: bb.1:
|
||||
bb.0:
|
||||
liveins: $x0
|
||||
successors: %bb.0, %bb.1
|
||||
@ -110,3 +117,80 @@ body: |
|
||||
|
||||
bb.1:
|
||||
...
|
||||
---
|
||||
name: test_rhs_inttoptr
|
||||
alignment: 2
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
; CHECK-LABEL: name: test_rhs_inttoptr
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
|
||||
; CHECK: CBZX [[COPY]], %bb.2
|
||||
; CHECK: bb.1:
|
||||
; CHECK: successors: %bb.2(0x80000000)
|
||||
; CHECK: STRXui $xzr, [[COPY]], 0 :: (store 8 into %ir.p)
|
||||
; CHECK: bb.2:
|
||||
; CHECK: RET_ReallyLR
|
||||
bb.1:
|
||||
successors: %bb.2, %bb.3
|
||||
liveins: $x0
|
||||
|
||||
%0:gpr(p0) = COPY $x0
|
||||
%2:gpr(s64) = G_CONSTANT i64 0
|
||||
%1:gpr(p0) = G_INTTOPTR %2(s64)
|
||||
%4:gpr(s32) = G_ICMP intpred(eq), %0(p0), %1
|
||||
%3:gpr(s1) = G_TRUNC %4(s32)
|
||||
G_BRCOND %3(s1), %bb.3
|
||||
|
||||
bb.2:
|
||||
%5:gpr(s64) = G_CONSTANT i64 0
|
||||
G_STORE %5(s64), %0(p0) :: (store 8 into %ir.p)
|
||||
|
||||
bb.3:
|
||||
RET_ReallyLR
|
||||
|
||||
...
|
||||
---
|
||||
name: test_rhs_unknown
|
||||
alignment: 2
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
; CHECK-LABEL: name: test_rhs_unknown
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
|
||||
; CHECK: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui [[COPY]], 0 :: (load 8 from %ir.p)
|
||||
; CHECK: $xzr = SUBSXri [[LDRXui]], 42, 0, implicit-def $nzcv
|
||||
; CHECK: Bcc 0, %bb.2, implicit $nzcv
|
||||
; CHECK: bb.1:
|
||||
; CHECK: successors: %bb.2(0x80000000)
|
||||
; CHECK: STRXui $xzr, [[COPY]], 0 :: (store 8 into %ir.p)
|
||||
; CHECK: bb.2:
|
||||
; CHECK: RET_ReallyLR
|
||||
bb.1:
|
||||
successors: %bb.2, %bb.3
|
||||
liveins: $x0
|
||||
|
||||
%0:gpr(p0) = COPY $x0
|
||||
%2:gpr(s64) = G_CONSTANT i64 42
|
||||
%4:gpr(s64) = G_CONSTANT i64 0
|
||||
%1:gpr(s64) = G_LOAD %0(p0) :: (load 8 from %ir.p)
|
||||
%5:gpr(s32) = G_ICMP intpred(eq), %1(s64), %2
|
||||
%3:gpr(s1) = G_TRUNC %5(s32)
|
||||
G_BRCOND %3(s1), %bb.3
|
||||
|
||||
bb.2:
|
||||
%6:gpr(s64) = G_CONSTANT i64 0
|
||||
G_STORE %6(s64), %0(p0) :: (store 8 into %ir.p)
|
||||
|
||||
bb.3:
|
||||
RET_ReallyLR
|
||||
|
||||
...
|
||||
|
@ -62,8 +62,7 @@ body: |
|
||||
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[SUBSWri]], %subreg.sub_32
|
||||
; CHECK: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[SUBREG_TO_REG]], 0, 31
|
||||
; CHECK: $xzr = SUBSXri [[UBFMXri]], 71, 0, implicit-def $nzcv
|
||||
; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv
|
||||
; CHECK: TBNZW [[CSINCWr]], 0, %bb.4
|
||||
; CHECK: Bcc 8, %bb.4, implicit $nzcv
|
||||
; CHECK: bb.1.entry:
|
||||
; CHECK: successors: %bb.3(0x2aaaaaab), %bb.4(0x2aaaaaab), %bb.2(0x2aaaaaab)
|
||||
; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 0
|
||||
|
@ -28,12 +28,9 @@ entry:
|
||||
define float @caller(i8* %error_ref) {
|
||||
; CHECK-LABEL: caller:
|
||||
; CHECK: mov [[ID:x[0-9]+]], x0
|
||||
; CHECK: mov [[ZERO:x[0-9]+]], #0
|
||||
; CHECK: mov x21, #0
|
||||
; CHECK: bl {{.*}}foo
|
||||
; CHECK: mov x0, x21
|
||||
; CHECK: cmp x21, [[ZERO]]
|
||||
; CHECK: b.ne
|
||||
; CHECK: cbnz x21
|
||||
; Access part of the error object and save it to error_ref
|
||||
; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]
|
||||
; CHECK: strb [[CODE]], [{{.*}}[[ID]]]
|
||||
@ -61,12 +58,10 @@ handler:
|
||||
define float @caller2(i8* %error_ref) {
|
||||
; CHECK-LABEL: caller2:
|
||||
; CHECK: mov [[ID:x[0-9]+]], x0
|
||||
; CHECK: mov [[ZERO:x[0-9]+]], #0
|
||||
; CHECK: fmov [[CMP:s[0-9]+]], #1.0
|
||||
; CHECK: mov x21, #0
|
||||
; CHECK: bl {{.*}}foo
|
||||
; CHECK: cmp x21, [[ZERO]]
|
||||
; CHECK: b.ne
|
||||
; CHECK: cbnz x21
|
||||
; CHECK: fcmp s0, [[CMP]]
|
||||
; CHECK: b.le
|
||||
; Access part of the error object and save it to error_ref
|
||||
@ -193,11 +188,9 @@ define float @caller3(i8* %error_ref) {
|
||||
; CHECK-LABEL: caller3:
|
||||
; CHECK: mov [[ID:x[0-9]+]], x0
|
||||
; CHECK: mov [[ZERO:x[0-9]+]], #0
|
||||
; CHECK: mov x21, #0
|
||||
; CHECK: bl {{.*}}foo_sret
|
||||
; CHECK: mov x0, x21
|
||||
; CHECK: cmp x21, [[ZERO]]
|
||||
; CHECK: b.ne
|
||||
; CHECK: cbnz x21
|
||||
; Access part of the error object and save it to error_ref
|
||||
; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]
|
||||
; CHECK: strb [[CODE]], [{{.*}}[[ID]]]
|
||||
@ -272,15 +265,13 @@ define float @caller4(i8* %error_ref) {
|
||||
; CHECK-LABEL: caller4:
|
||||
|
||||
; CHECK: mov [[ID:x[0-9]+]], x0
|
||||
; CHECK: mov [[ZERO:x[0-9]+]], #0
|
||||
; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp]
|
||||
; CHECK: mov x21, #0
|
||||
; CHECK: str {{x[0-9]+}}, [sp, #16]
|
||||
|
||||
; CHECK: bl {{.*}}foo_vararg
|
||||
; CHECK: mov x0, x21
|
||||
; CHECK: cmp x21, [[ZERO]]
|
||||
; CHECK: b.ne
|
||||
; CHECK: cbnz x21
|
||||
; Access part of the error object and save it to error_ref
|
||||
; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]
|
||||
; CHECK: strb [[CODE]], [{{.*}}[[ID]]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user