[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