summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2019-07-10 19:21:43 +0000
committerAmara Emerson <aemerson@apple.com>2019-07-10 19:21:43 +0000
commit7a4d2df04a932fcc859d7f25c5a60253b99380f7 (patch)
treeeb1d5f49c63746376f65d6730bc440ce5c25404b
parent5f5237c2764b504ce764af17ab06eec71073a653 (diff)
downloadbcm5719-llvm-7a4d2df04a932fcc859d7f25c5a60253b99380f7.tar.gz
bcm5719-llvm-7a4d2df04a932fcc859d7f25c5a60253b99380f7.zip
[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
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Utils.cpp3
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp19
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir132
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir3
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll17
5 files changed, 131 insertions, 43 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index deccdc6c750..766ea1d60ba 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -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;
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 41b58504daf..4e13fb8e202 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -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)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir
index 4075ba279c7..c8fd3069d73 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir
@@ -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
+
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir
index 85b32e12903..bf71804af34 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir
@@ -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
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll b/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
index 83e48a6a504..386771fa94f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
@@ -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]]]
OpenPOWER on IntegriCloud