[llvm] 8e8664e - [AArch64][GlobalISel] Use emitTestBit in selection for G_BRCOND
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 15:33:44 PDT 2020
Author: Jessica Paquette
Date: 2020-10-01T15:33:34-07:00
New Revision: 8e8664e55e8986e061283cb20c30f21fb2d2b641
URL: https://github.com/llvm/llvm-project/commit/8e8664e55e8986e061283cb20c30f21fb2d2b641
DIFF: https://github.com/llvm/llvm-project/commit/8e8664e55e8986e061283cb20c30f21fb2d2b641.diff
LOG: [AArch64][GlobalISel] Use emitTestBit in selection for G_BRCOND
Partially refactoring, partially fixing a bug.
- We shouldn't use TB(N)ZX unless the bit number is >= 32
- We can fold more than xor using emitTestBit
Also remove a check which isn't relevant anymore + update tests.
Rename select-brcond-of-not.mir to select-brcond-of-binop.mir, since it now
tests more than just G_XOR.
Differential Revision: https://reviews.llvm.org/D88702
Added:
llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir
Modified:
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
llvm/test/CodeGen/AArch64/GlobalISel/select.mir
llvm/test/CodeGen/AArch64/GlobalISel/widen-narrow-tbz-tbnz.mir
Removed:
llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-not.mir
################################################################################
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index bb132a33ac5b..db6e88b01599 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -1959,15 +1959,6 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
switch (Opcode) {
case TargetOpcode::G_BRCOND: {
- if (Ty.getSizeInBits() > 32) {
- // We shouldn't need this on AArch64, but it would be implemented as an
- // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the
- // bit being tested is < 32.
- LLVM_DEBUG(dbgs() << "G_BRCOND has type: " << Ty
- << ", expected at most 32-bits");
- return false;
- }
-
Register CondReg = I.getOperand(0).getReg();
MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
@@ -1978,25 +1969,10 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return true;
if (ProduceNonFlagSettingCondBr) {
- unsigned BOpc = AArch64::TBNZW;
- // Try to fold a not, i.e. a xor, cond, 1.
- Register XorSrc;
- int64_t Cst;
- if (mi_match(CondReg, MRI,
- m_GTrunc(m_GXor(m_Reg(XorSrc), m_ICst(Cst)))) &&
- Cst == 1) {
- CondReg = XorSrc;
- BOpc = AArch64::TBZW;
- if (MRI.getType(XorSrc).getSizeInBits() > 32)
- BOpc = AArch64::TBZX;
- }
- auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(BOpc))
- .addUse(CondReg)
- .addImm(/*bit offset=*/0)
- .addMBB(DestMBB);
-
+ auto TestBit = emitTestBit(CondReg, /*Bit = */ 0, /*IsNegative = */ true,
+ DestMBB, MIB);
I.eraseFromParent();
- return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
+ return constrainSelectedInstRegOperands(*TestBit, TII, TRI, RBI);
} else {
auto CMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
.addDef(AArch64::WZR)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir
new file mode 100644
index 000000000000..9d480b8e96e0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir
@@ -0,0 +1,235 @@
+# 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
+---
+name: condbr_of_not
+legalized: true
+regBankSelected: true
+liveins:
+ - { reg: '$x0' }
+body: |
+ ; CHECK-LABEL: name: condbr_of_not
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
+ ; CHECK: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load 1)
+ ; CHECK: TBZW [[LDRBBui]], 0, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $x0
+
+ %0:gpr(p0) = COPY $x0
+ %8:gpr(s8) = G_LOAD %0(p0) :: (load 1)
+ %4:gpr(s32) = G_ANYEXT %8(s8)
+ %5:gpr(s32) = G_CONSTANT i32 1
+ %6:gpr(s32) = G_XOR %4, %5
+ %3:gpr(s1) = G_TRUNC %6(s32)
+ G_BRCOND %3(s1), %bb.3
+
+ bb.2:
+ RET_ReallyLR
+
+ bb.3:
+ RET_ReallyLR
+
+...
+---
+name: condbr_of_not_64
+legalized: true
+regBankSelected: true
+liveins:
+ - { reg: '$x0' }
+body: |
+ ; CHECK-LABEL: name: condbr_of_not_64
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
+ ; CHECK: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load 1)
+ ; CHECK: TBZW [[LDRBBui]], 0, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ ; TB(N)ZX has no encoding if the bit being tested is < 32, so we should get
+ ; TBZW here.
+ ;
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $x0
+
+ %0:gpr(p0) = COPY $x0
+ %8:gpr(s8) = G_LOAD %0(p0) :: (load 1)
+ %4:gpr(s64) = G_ANYEXT %8(s8)
+ %5:gpr(s64) = G_CONSTANT i64 1
+ %6:gpr(s64) = G_XOR %4, %5
+ %3:gpr(s1) = G_TRUNC %6(s64)
+ G_BRCOND %3(s1), %bb.3
+
+ bb.2:
+ RET_ReallyLR
+
+ bb.3:
+ RET_ReallyLR
+
+...
+---
+name: condbr_of_and
+legalized: true
+regBankSelected: true
+body: |
+ ; CHECK-LABEL: name: condbr_of_and
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: %lhs:gpr32 = COPY $w0
+ ; CHECK: TBNZW %lhs, 0, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $w0
+ %lhs:gpr(s32) = COPY $w0
+ %rhs:gpr(s32) = G_CONSTANT i32 1
+ %op:gpr(s32) = G_AND %lhs, %rhs
+ %trunc:gpr(s1) = G_TRUNC %op(s32)
+ G_BRCOND %trunc(s1), %bb.3
+
+ bb.2:
+ RET_ReallyLR
+
+ bb.3:
+ RET_ReallyLR
+
+...
+---
+name: condbr_of_and_no_cst
+legalized: true
+regBankSelected: true
+body: |
+ ; CHECK-LABEL: name: condbr_of_and_no_cst
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: %lhs:gpr32 = COPY $w0
+ ; CHECK: %rhs:gpr32 = COPY $w1
+ ; CHECK: %op:gpr32 = ANDWrr %lhs, %rhs
+ ; CHECK: TBNZW %op, 0, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $w0, $w1
+ %lhs:gpr(s32) = COPY $w0
+ %rhs:gpr(s32) = COPY $w1
+ %op:gpr(s32) = G_AND %lhs, %rhs
+ %trunc:gpr(s1) = G_TRUNC %op(s32)
+ G_BRCOND %trunc(s1), %bb.3
+
+ bb.2:
+ RET_ReallyLR
+
+ bb.3:
+ RET_ReallyLR
+
+...
+---
+name: condbr_of_shl
+legalized: true
+regBankSelected: true
+body: |
+ ; CHECK-LABEL: name: condbr_of_shl
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: %lhs:gpr32 = COPY $w0
+ ; CHECK: %op:gpr32 = UBFMWri %lhs, 31, 30
+ ; CHECK: TBNZW %op, 0, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ ; We won't ever fold this, because
+ ; bit = 0
+ ; bit - constant < 0, which isn't valid for tbz/tbnz.
+ ;
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $w0
+ %lhs:gpr(s32) = COPY $w0
+ %rhs:gpr(s32) = G_CONSTANT i32 1
+ %op:gpr(s32) = G_SHL %lhs, %rhs
+ %trunc:gpr(s1) = G_TRUNC %op(s32)
+ G_BRCOND %trunc(s1), %bb.3
+
+ bb.2:
+ RET_ReallyLR
+
+ bb.3:
+ RET_ReallyLR
+
+...
+---
+name: condbr_of_ashr
+legalized: true
+regBankSelected: true
+body: |
+ ; CHECK-LABEL: name: condbr_of_ashr
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: %lhs:gpr32 = COPY $w0
+ ; CHECK: TBNZW %lhs, 1, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ ; We can fold ashr, because we can have
+ ;
+ ; (tbz (ashr x, c), 0) where 0 + c > # bits in x.
+ ;
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $w0
+ %lhs:gpr(s32) = COPY $w0
+ %rhs:gpr(s32) = G_CONSTANT i32 1
+ %op:gpr(s32) = G_ASHR %lhs, %rhs
+ %trunc:gpr(s1) = G_TRUNC %op(s32)
+ G_BRCOND %trunc(s1), %bb.3
+
+ bb.2:
+ RET_ReallyLR
+
+ bb.3:
+ RET_ReallyLR
+
+...
+---
+name: tbnzx
+legalized: true
+regBankSelected: true
+body: |
+ ; CHECK-LABEL: name: tbnzx
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK: %lhs:gpr64 = COPY $x0
+ ; CHECK: TBNZX %lhs, 63, %bb.2
+ ; CHECK: bb.1:
+ ; CHECK: RET_ReallyLR
+ ; CHECK: bb.2:
+ ; CHECK: RET_ReallyLR
+ bb.1:
+ successors: %bb.2, %bb.3
+ liveins: $x0
+ %lhs:gpr(s64) = COPY $x0
+ %rhs:gpr(s64) = G_CONSTANT i64 8589934592
+ %op:gpr(s64) = G_ASHR %lhs, %rhs
+ %trunc:gpr(s1) = G_TRUNC %op(s64)
+ G_BRCOND %trunc(s1), %bb.3
+ bb.2:
+ RET_ReallyLR
+ bb.3:
+ RET_ReallyLR
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-not.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-not.mir
deleted file mode 100644
index 41fe50d9bb7d..000000000000
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-not.mir
+++ /dev/null
@@ -1,76 +0,0 @@
-# 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
----
-name: condbr_of_not
-legalized: true
-regBankSelected: true
-liveins:
- - { reg: '$x0' }
-body: |
- ; CHECK-LABEL: name: condbr_of_not
- ; CHECK: bb.0:
- ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
- ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
- ; CHECK: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load 1)
- ; CHECK: TBZW [[LDRBBui]], 0, %bb.2
- ; CHECK: bb.1:
- ; CHECK: RET_ReallyLR
- ; CHECK: bb.2:
- ; CHECK: RET_ReallyLR
- bb.1:
- successors: %bb.2, %bb.3
- liveins: $x0
-
- %0:gpr(p0) = COPY $x0
- %8:gpr(s8) = G_LOAD %0(p0) :: (load 1)
- %4:gpr(s32) = G_ANYEXT %8(s8)
- %5:gpr(s32) = G_CONSTANT i32 1
- %6:gpr(s32) = G_XOR %4, %5
- %3:gpr(s1) = G_TRUNC %6(s32)
- G_BRCOND %3(s1), %bb.3
-
- bb.2:
- RET_ReallyLR
-
- bb.3:
- RET_ReallyLR
-
-...
----
-name: condbr_of_not_64
-legalized: true
-regBankSelected: true
-liveins:
- - { reg: '$x0' }
-body: |
- ; CHECK-LABEL: name: condbr_of_not_64
- ; CHECK: bb.0:
- ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
- ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
- ; CHECK: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load 1)
- ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, [[LDRBBui]], %subreg.sub_32
- ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]]
- ; CHECK: TBZX [[COPY1]], 0, %bb.2
- ; CHECK: bb.1:
- ; CHECK: RET_ReallyLR
- ; CHECK: bb.2:
- ; CHECK: RET_ReallyLR
- bb.1:
- successors: %bb.2, %bb.3
- liveins: $x0
-
- %0:gpr(p0) = COPY $x0
- %8:gpr(s8) = G_LOAD %0(p0) :: (load 1)
- %4:gpr(s64) = G_ANYEXT %8(s8)
- %5:gpr(s64) = G_CONSTANT i64 1
- %6:gpr(s64) = G_XOR %4, %5
- %3:gpr(s1) = G_TRUNC %6(s64)
- G_BRCOND %3(s1), %bb.3
-
- bb.2:
- RET_ReallyLR
-
- bb.3:
- RET_ReallyLR
-
-...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select.mir
index 112aee8d552c..a2a41a8aaa31 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select.mir
@@ -223,8 +223,9 @@ tracksRegLiveness: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: fpr32, preferred-register: '' }
-# CHECK-NEXT: - { id: 1, class: gpr32, preferred-register: '' }
+# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
# CHECK-NEXT: - { id: 2, class: fpr32, preferred-register: '' }
+# CHECK-NEXT: - { id: 3, class: gpr32, preferred-register: '' }
registers:
- { id: 0, class: fpr }
- { id: 1, class: gpr }
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/widen-narrow-tbz-tbnz.mir b/llvm/test/CodeGen/AArch64/GlobalISel/widen-narrow-tbz-tbnz.mir
index 22963c50a2eb..0794e2a3e58a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/widen-narrow-tbz-tbnz.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/widen-narrow-tbz-tbnz.mir
@@ -174,9 +174,10 @@ body: |
; CHECK: bb.0:
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
; CHECK: liveins: $x0
- ; CHECK: %wide:gpr64 = COPY $x0
- ; CHECK: %trunc:gpr32 = COPY %wide.sub_32
- ; CHECK: TBNZW %trunc, 0, %bb.1
+ ; CHECK: %wide:gpr64all = COPY $x0
+ ; CHECK: [[COPY:%[0-9]+]]:gpr32all = COPY %wide.sub_32
+ ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
+ ; CHECK: TBNZW [[COPY1]], 0, %bb.1
; CHECK: B %bb.0
; CHECK: bb.1:
; CHECK: RET_ReallyLR
More information about the llvm-commits
mailing list