[llvm] e20f69f - [Aarch64] Correct register class for pseudo instructions

Jameson Nash via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 9 11:32:15 PDT 2021


Author: Jameson Nash
Date: 2021-09-09T14:31:49-04:00
New Revision: e20f69f612dd678f68473e3f111ee891f7d2d108

URL: https://github.com/llvm/llvm-project/commit/e20f69f612dd678f68473e3f111ee891f7d2d108
DIFF: https://github.com/llvm/llvm-project/commit/e20f69f612dd678f68473e3f111ee891f7d2d108.diff

LOG: [Aarch64] Correct register class for pseudo instructions

This constrains the Mov* and similar pseudo instruction to take
GPR64common register classes rather than GPR64. GPR64 includs XZR
which is invalid here, because this pseudo instructions expands
into an adrp/add pair sharing a destination register. XZR is invalid
on add and attempting to encode it will instead increment the stack
pointer causing crashes (downstream report at [1]). The test case
there reproduces on LLVM11, but I do not have a test case that
reaches this code path on main, since it is being masked by
improved dead code elimination introduced in D91513. Nevertheless,
this seems like a good thing to fix in case there are other cases
that dead code elimination doesn't clean up (e.g. if `optnone` is
used and the optimization is skipped).

I think it would be worth auditing uses of GPR64 in pseudo
instructions to see if there are any similar issues, but I do not
have a high enough view of the backend or knowledge of the
Aarch64 architecture to do this quickly.

[1] https://github.com/JuliaLang/julia/issues/39818

Reviewed By: t.p.northover

Differential Revision: https://reviews.llvm.org/D97435

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
    llvm/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/test/CodeGen/AArch64/GlobalISel/select-add-low.mir
    llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
    llvm/test/CodeGen/AArch64/GlobalISel/select-gv-with-offset.mir
    llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir
    llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir
    llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir
    llvm/test/CodeGen/AArch64/GlobalISel/select.mir
    llvm/test/CodeGen/AArch64/elim-dead-mi.mir
    llvm/test/CodeGen/AArch64/loop-sink.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 1c05d6235e02f..4c04e04a7d3c5 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -1053,6 +1053,7 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
   case AArch64::MOVaddrEXT: {
     // Expand into ADRP + ADD.
     Register DstReg = MI.getOperand(0).getReg();
+    assert(DstReg != AArch64::XZR);
     MachineInstrBuilder MIB1 =
         BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg)
             .add(MI.getOperand(1));

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index e949f66375283..0c7198e4ccdb0 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -688,40 +688,40 @@ let isReMaterializable = 1, isCodeGenOnly = 1 in {
 // removed, along with the AArch64Wrapper node.
 
 let AddedComplexity = 10 in
-def LOADgot : Pseudo<(outs GPR64:$dst), (ins i64imm:$addr),
-                     [(set GPR64:$dst, (AArch64LOADgot tglobaladdr:$addr))]>,
+def LOADgot : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr),
+                     [(set GPR64common:$dst, (AArch64LOADgot tglobaladdr:$addr))]>,
               Sched<[WriteLDAdr]>;
 
 // The MOVaddr instruction should match only when the add is not folded
 // into a load or store address.
 def MOVaddr
-    : Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow (AArch64adrp tglobaladdr:$hi),
+    : Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
+             [(set GPR64common:$dst, (AArch64addlow (AArch64adrp tglobaladdr:$hi),
                                             tglobaladdr:$low))]>,
       Sched<[WriteAdrAdr]>;
 def MOVaddrJT
-    : Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow (AArch64adrp tjumptable:$hi),
+    : Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
+             [(set GPR64common:$dst, (AArch64addlow (AArch64adrp tjumptable:$hi),
                                              tjumptable:$low))]>,
       Sched<[WriteAdrAdr]>;
 def MOVaddrCP
-    : Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow (AArch64adrp tconstpool:$hi),
+    : Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
+             [(set GPR64common:$dst, (AArch64addlow (AArch64adrp tconstpool:$hi),
                                              tconstpool:$low))]>,
       Sched<[WriteAdrAdr]>;
 def MOVaddrBA
-    : Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow (AArch64adrp tblockaddress:$hi),
+    : Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
+             [(set GPR64common:$dst, (AArch64addlow (AArch64adrp tblockaddress:$hi),
                                              tblockaddress:$low))]>,
       Sched<[WriteAdrAdr]>;
 def MOVaddrTLS
-    : Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow (AArch64adrp tglobaltlsaddr:$hi),
+    : Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
+             [(set GPR64common:$dst, (AArch64addlow (AArch64adrp tglobaltlsaddr:$hi),
                                             tglobaltlsaddr:$low))]>,
       Sched<[WriteAdrAdr]>;
 def MOVaddrEXT
-    : Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow (AArch64adrp texternalsym:$hi),
+    : Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
+             [(set GPR64common:$dst, (AArch64addlow (AArch64adrp texternalsym:$hi),
                                             texternalsym:$low))]>,
       Sched<[WriteAdrAdr]>;
 // Normally AArch64addlow either gets folded into a following ldr/str,
@@ -729,8 +729,8 @@ def MOVaddrEXT
 // might appear without either of them, so allow lowering it into a plain
 // add.
 def ADDlowTLS
-    : Pseudo<(outs GPR64:$dst), (ins GPR64:$src, i64imm:$low),
-             [(set GPR64:$dst, (AArch64addlow GPR64:$src,
+    : Pseudo<(outs GPR64sp:$dst), (ins GPR64sp:$src, i64imm:$low),
+             [(set GPR64sp:$dst, (AArch64addlow GPR64sp:$src,
                                             tglobaltlsaddr:$low))]>,
       Sched<[WriteAdr]>;
 

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-add-low.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-add-low.mir
index 2272aaf286733..e29568698f8b2 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-add-low.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-add-low.mir
@@ -20,7 +20,7 @@ body:             |
     liveins: $x0
     ; CHECK-LABEL: name: select_add_low_without_offset
     ; CHECK: liveins: $x0
-    ; CHECK: %add_low:gpr64 = MOVaddr target-flags(aarch64-page) @x, target-flags(aarch64-pageoff, aarch64-nc) @x
+    ; CHECK: %add_low:gpr64common = MOVaddr target-flags(aarch64-page) @x, target-flags(aarch64-pageoff, aarch64-nc) @x
     ; CHECK: $x0 = COPY %add_low
     ; CHECK: RET_ReallyLR implicit $x0
     %copy:gpr(p0) = COPY $x0
@@ -40,7 +40,7 @@ body:             |
     liveins: $x0
     ; CHECK-LABEL: name: select_add_low_with_offset
     ; CHECK: liveins: $x0
-    ; CHECK: %add_low:gpr64 = MOVaddr target-flags(aarch64-page) @x + 1, target-flags(aarch64-pageoff, aarch64-nc) @x + 1
+    ; CHECK: %add_low:gpr64common = MOVaddr target-flags(aarch64-page) @x + 1, target-flags(aarch64-pageoff, aarch64-nc) @x + 1
     ; CHECK: $x0 = COPY %add_low
     ; CHECK: RET_ReallyLR implicit $x0
     %copy:gpr(p0) = COPY $x0

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
index 1f63da4d12c59..0737a8ed871f1 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
@@ -30,9 +30,10 @@ registers:
 body:             |
   ; CHECK-LABEL: name: test_blockaddress
   ; CHECK: bb.0 (%ir-block.0):
-  ; CHECK:   [[MOVaddrBA:%[0-9]+]]:gpr64 = MOVaddrBA target-flags(aarch64-page) blockaddress(@test_blockaddress, %ir-block.block), target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block)
+  ; CHECK:   [[MOVaddrBA:%[0-9]+]]:gpr64common = MOVaddrBA target-flags(aarch64-page) blockaddress(@test_blockaddress, %ir-block.block), target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block)
   ; CHECK:   [[MOVaddr:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @addr, target-flags(aarch64-pageoff, aarch64-nc) @addr
-  ; CHECK:   STRXui [[MOVaddrBA]], [[MOVaddr]], 0 :: (store (p0) into @addr)
+  ; CHECK:   [[COPY:%[0-9]+]]:gpr64 = COPY [[MOVaddrBA]]
+  ; CHECK:   STRXui [[COPY]], [[MOVaddr]], 0 :: (store (p0) into @addr)
   ; CHECK:   BR [[MOVaddrBA]]
   ; CHECK: bb.1.block (address-taken):
   ; CHECK:   RET_ReallyLR

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-with-offset.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-with-offset.mir
index 7533731b2bd8e..8b4ae941eb4d7 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-with-offset.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-with-offset.mir
@@ -25,7 +25,7 @@ body:             |
     ; LARGE: RET_ReallyLR implicit $x0
     ; SMALL-LABEL: name: select_gv_with_offset
     ; SMALL: liveins: $x0
-    ; SMALL: %g:gpr64 = MOVaddr target-flags(aarch64-page) @g + 1, target-flags(aarch64-pageoff, aarch64-nc) @g + 1
+    ; SMALL: %g:gpr64common = MOVaddr target-flags(aarch64-page) @g + 1, target-flags(aarch64-pageoff, aarch64-nc) @g + 1
     ; SMALL: $x0 = COPY %g
     ; SMALL: RET_ReallyLR implicit $x0
     ; TINY-LABEL: name: select_gv_with_offset

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir
index affaef15856e7..1aec09b69680b 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir
@@ -30,7 +30,7 @@ body:             |
   ; CHECK:   Bcc 8, %bb.3, implicit $nzcv
   ; CHECK: bb.1:
   ; CHECK:   successors: %bb.2(0x40000000), %bb.3(0x40000000)
-  ; CHECK:   [[MOVaddrJT:%[0-9]+]]:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
+  ; CHECK:   [[MOVaddrJT:%[0-9]+]]:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
   ; CHECK:   early-clobber %6:gpr64, early-clobber %7:gpr64sp = JumpTableDest32 [[MOVaddrJT]], [[SUBREG_TO_REG]], %jump-table.0
   ; CHECK:   BR %6
   ; CHECK: bb.2:

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 6b84c6d108437..b8c9a6c881da7 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir
@@ -65,7 +65,7 @@ body:             |
   ; CHECK: bb.1.entry:
   ; CHECK:   successors: %bb.3(0x2aaaaaab), %bb.4(0x2aaaaaab), %bb.2(0x2aaaaaab)
   ; CHECK:   [[COPY2:%[0-9]+]]:gpr32 = COPY $wzr
-  ; CHECK:   [[MOVaddrJT:%[0-9]+]]:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
+  ; CHECK:   [[MOVaddrJT:%[0-9]+]]:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
   ; CHECK:   early-clobber %18:gpr64, early-clobber %19:gpr64sp = JumpTableDest32 [[MOVaddrJT]], [[SUBREG_TO_REG]], %jump-table.0
   ; CHECK:   BR %18
   ; CHECK: bb.2.sw.bb:

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir
index 0151b1f62303c..dff2f093a9a4b 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir
@@ -75,7 +75,7 @@ registers:
   - { id: 0, class: gpr }
 
 # CHECK:  body:
-# LINUX-DEFAULT: %0:gpr64 = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
+# LINUX-DEFAULT: %0:gpr64common = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
 body:             |
   bb.0:
     %0(p0) = G_GLOBAL_VALUE @var_local
@@ -91,7 +91,7 @@ registers:
   - { id: 0, class: gpr }
 
 # CHECK:  body:
-# LINUX-DEFAULT: %0:gpr64 = MOVaddr target-flags(aarch64-page) @var_got, target-flags(aarch64-pageoff, aarch64-nc) @var_got
+# LINUX-DEFAULT: %0:gpr64common = MOVaddr target-flags(aarch64-page) @var_got, target-flags(aarch64-pageoff, aarch64-nc) @var_got
 body:             |
   bb.0:
     %0(p0) = G_GLOBAL_VALUE @var_got

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select.mir
index f8e65c76568b4..0cc52852378fe 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select.mir
@@ -76,8 +76,8 @@ registers:
   - { id: 0, class: gpr }
 
 # CHECK:  body:
-# IOS: %0:gpr64 = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
-# LINUX-PIC: %0:gpr64 = LOADgot target-flags(aarch64-got) @var_local
+# IOS: %0:gpr64common = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
+# LINUX-PIC: %0:gpr64common = LOADgot target-flags(aarch64-got) @var_local
 body:             |
   bb.0:
     %0(p0) = G_GLOBAL_VALUE @var_local
@@ -93,8 +93,8 @@ registers:
   - { id: 0, class: gpr }
 
 # CHECK:  body:
-# IOS: %0:gpr64 = LOADgot target-flags(aarch64-got) @var_got
-# LINUX-PIC: %0:gpr64 = LOADgot target-flags(aarch64-got) @var_got
+# IOS: %0:gpr64common = LOADgot target-flags(aarch64-got) @var_got
+# LINUX-PIC: %0:gpr64common = LOADgot target-flags(aarch64-got) @var_got
 body:             |
   bb.0:
     %0(p0) = G_GLOBAL_VALUE @var_got

diff  --git a/llvm/test/CodeGen/AArch64/elim-dead-mi.mir b/llvm/test/CodeGen/AArch64/elim-dead-mi.mir
index bfbd9a529a065..c7518c9324742 100644
--- a/llvm/test/CodeGen/AArch64/elim-dead-mi.mir
+++ b/llvm/test/CodeGen/AArch64/elim-dead-mi.mir
@@ -13,18 +13,18 @@
 name:            main
 tracksRegLiveness: true
 registers:
-  - { id: 0, class: gpr64, preferred-register: '' }
+  - { id: 0, class: gpr64common, preferred-register: '' }
   - { id: 1, class: gpr64common, preferred-register: '' }
   - { id: 2, class: gpr64, preferred-register: '' }
   - { id: 3, class: gpr64common, preferred-register: '' }
   - { id: 4, class: gpr32, preferred-register: '' }
   - { id: 5, class: gpr32all, preferred-register: '' }
-  - { id: 6, class: gpr64, preferred-register: '' }
+  - { id: 6, class: gpr64common, preferred-register: '' }
 body:             |
   bb.0:
     successors: %bb.4(0x30000000), %bb.5(0x50000000)
 
-    %0:gpr64 = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
+    %0:gpr64common = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
     CBZX killed %0, %bb.4
     B %bb.5
 
@@ -55,7 +55,7 @@ body:             |
   bb.5:
     successors: %bb.1(0x80000000)
     ; CHECK: bb.5
-    ; CHECK-NOT: %6:gpr64 = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
-    %6:gpr64 = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
+    ; CHECK-NOT: %6:gpr64common = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
+    %6:gpr64common = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
     B %bb.1
 ...

diff  --git a/llvm/test/CodeGen/AArch64/loop-sink.mir b/llvm/test/CodeGen/AArch64/loop-sink.mir
index 091183bf492c3..124f55bc9b9ad 100644
--- a/llvm/test/CodeGen/AArch64/loop-sink.mir
+++ b/llvm/test/CodeGen/AArch64/loop-sink.mir
@@ -274,7 +274,7 @@ registers:
   - { id: 17, class: gpr32, preferred-register: '' }
   - { id: 18, class: gpr32sp, preferred-register: '' }
   - { id: 19, class: gpr32, preferred-register: '' }
-  - { id: 20, class: gpr64, preferred-register: '' }
+  - { id: 20, class: gpr64common, preferred-register: '' }
   - { id: 21, class: gpr64, preferred-register: '' }
   - { id: 22, class: gpr64sp, preferred-register: '' }
   - { id: 23, class: gpr64sp, preferred-register: '' }
@@ -338,7 +338,7 @@ body:             |
   ; CHECK:   [[COPY6:%[0-9]+]]:gpr64all = COPY [[ADDXri4]]
   ; CHECK:   [[ADDXri5:%[0-9]+]]:gpr64sp = ADDXri [[COPY1]], 1, 0
   ; CHECK:   [[COPY7:%[0-9]+]]:gpr64all = COPY [[ADDXri5]]
-  ; CHECK:   [[MOVaddrJT:%[0-9]+]]:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
+  ; CHECK:   [[MOVaddrJT:%[0-9]+]]:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
   ; CHECK: bb.1..backedge:
   ; CHECK:   successors: %bb.9(0x09249249), %bb.2(0x76db6db7)
   ; CHECK:   [[PHI:%[0-9]+]]:gpr64sp = PHI [[COPY7]], %bb.0, %7, %bb.9
@@ -415,7 +415,7 @@ body:             |
     %4:gpr64all = COPY %14
     %15:gpr64sp = ADDXri %8, 1, 0
     %5:gpr64all = COPY %15
-    %20:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
+    %20:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
 
   bb.1..backedge:
     successors: %bb.8(0x09249249), %bb.9(0x76db6db7)


        


More information about the llvm-commits mailing list