Skip to content

Commit e20f69f

Browse files
committed
[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] JuliaLang/julia#39818 Reviewed By: t.p.northover Differential Revision: https://reviews.llvm.org/D97435
1 parent d99a83b commit e20f69f

11 files changed

+39
-37
lines changed

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,7 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
10531053
case AArch64::MOVaddrEXT: {
10541054
// Expand into ADRP + ADD.
10551055
Register DstReg = MI.getOperand(0).getReg();
1056+
assert(DstReg != AArch64::XZR);
10561057
MachineInstrBuilder MIB1 =
10571058
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg)
10581059
.add(MI.getOperand(1));

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -688,49 +688,49 @@ let isReMaterializable = 1, isCodeGenOnly = 1 in {
688688
// removed, along with the AArch64Wrapper node.
689689

690690
let AddedComplexity = 10 in
691-
def LOADgot : Pseudo<(outs GPR64:$dst), (ins i64imm:$addr),
692-
[(set GPR64:$dst, (AArch64LOADgot tglobaladdr:$addr))]>,
691+
def LOADgot : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr),
692+
[(set GPR64common:$dst, (AArch64LOADgot tglobaladdr:$addr))]>,
693693
Sched<[WriteLDAdr]>;
694694

695695
// The MOVaddr instruction should match only when the add is not folded
696696
// into a load or store address.
697697
def MOVaddr
698-
: Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
699-
[(set GPR64:$dst, (AArch64addlow (AArch64adrp tglobaladdr:$hi),
698+
: Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
699+
[(set GPR64common:$dst, (AArch64addlow (AArch64adrp tglobaladdr:$hi),
700700
tglobaladdr:$low))]>,
701701
Sched<[WriteAdrAdr]>;
702702
def MOVaddrJT
703-
: Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
704-
[(set GPR64:$dst, (AArch64addlow (AArch64adrp tjumptable:$hi),
703+
: Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
704+
[(set GPR64common:$dst, (AArch64addlow (AArch64adrp tjumptable:$hi),
705705
tjumptable:$low))]>,
706706
Sched<[WriteAdrAdr]>;
707707
def MOVaddrCP
708-
: Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
709-
[(set GPR64:$dst, (AArch64addlow (AArch64adrp tconstpool:$hi),
708+
: Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
709+
[(set GPR64common:$dst, (AArch64addlow (AArch64adrp tconstpool:$hi),
710710
tconstpool:$low))]>,
711711
Sched<[WriteAdrAdr]>;
712712
def MOVaddrBA
713-
: Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
714-
[(set GPR64:$dst, (AArch64addlow (AArch64adrp tblockaddress:$hi),
713+
: Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
714+
[(set GPR64common:$dst, (AArch64addlow (AArch64adrp tblockaddress:$hi),
715715
tblockaddress:$low))]>,
716716
Sched<[WriteAdrAdr]>;
717717
def MOVaddrTLS
718-
: Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
719-
[(set GPR64:$dst, (AArch64addlow (AArch64adrp tglobaltlsaddr:$hi),
718+
: Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
719+
[(set GPR64common:$dst, (AArch64addlow (AArch64adrp tglobaltlsaddr:$hi),
720720
tglobaltlsaddr:$low))]>,
721721
Sched<[WriteAdrAdr]>;
722722
def MOVaddrEXT
723-
: Pseudo<(outs GPR64:$dst), (ins i64imm:$hi, i64imm:$low),
724-
[(set GPR64:$dst, (AArch64addlow (AArch64adrp texternalsym:$hi),
723+
: Pseudo<(outs GPR64common:$dst), (ins i64imm:$hi, i64imm:$low),
724+
[(set GPR64common:$dst, (AArch64addlow (AArch64adrp texternalsym:$hi),
725725
texternalsym:$low))]>,
726726
Sched<[WriteAdrAdr]>;
727727
// Normally AArch64addlow either gets folded into a following ldr/str,
728728
// or together with an adrp into MOVaddr above. For cases with TLS, it
729729
// might appear without either of them, so allow lowering it into a plain
730730
// add.
731731
def ADDlowTLS
732-
: Pseudo<(outs GPR64:$dst), (ins GPR64:$src, i64imm:$low),
733-
[(set GPR64:$dst, (AArch64addlow GPR64:$src,
732+
: Pseudo<(outs GPR64sp:$dst), (ins GPR64sp:$src, i64imm:$low),
733+
[(set GPR64sp:$dst, (AArch64addlow GPR64sp:$src,
734734
tglobaltlsaddr:$low))]>,
735735
Sched<[WriteAdr]>;
736736

llvm/test/CodeGen/AArch64/GlobalISel/select-add-low.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ body: |
2020
liveins: $x0
2121
; CHECK-LABEL: name: select_add_low_without_offset
2222
; CHECK: liveins: $x0
23-
; CHECK: %add_low:gpr64 = MOVaddr target-flags(aarch64-page) @x, target-flags(aarch64-pageoff, aarch64-nc) @x
23+
; CHECK: %add_low:gpr64common = MOVaddr target-flags(aarch64-page) @x, target-flags(aarch64-pageoff, aarch64-nc) @x
2424
; CHECK: $x0 = COPY %add_low
2525
; CHECK: RET_ReallyLR implicit $x0
2626
%copy:gpr(p0) = COPY $x0
@@ -40,7 +40,7 @@ body: |
4040
liveins: $x0
4141
; CHECK-LABEL: name: select_add_low_with_offset
4242
; CHECK: liveins: $x0
43-
; CHECK: %add_low:gpr64 = MOVaddr target-flags(aarch64-page) @x + 1, target-flags(aarch64-pageoff, aarch64-nc) @x + 1
43+
; CHECK: %add_low:gpr64common = MOVaddr target-flags(aarch64-page) @x + 1, target-flags(aarch64-pageoff, aarch64-nc) @x + 1
4444
; CHECK: $x0 = COPY %add_low
4545
; CHECK: RET_ReallyLR implicit $x0
4646
%copy:gpr(p0) = COPY $x0

llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ registers:
3030
body: |
3131
; CHECK-LABEL: name: test_blockaddress
3232
; CHECK: bb.0 (%ir-block.0):
33-
; 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)
33+
; 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)
3434
; CHECK: [[MOVaddr:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @addr, target-flags(aarch64-pageoff, aarch64-nc) @addr
35-
; CHECK: STRXui [[MOVaddrBA]], [[MOVaddr]], 0 :: (store (p0) into @addr)
35+
; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY [[MOVaddrBA]]
36+
; CHECK: STRXui [[COPY]], [[MOVaddr]], 0 :: (store (p0) into @addr)
3637
; CHECK: BR [[MOVaddrBA]]
3738
; CHECK: bb.1.block (address-taken):
3839
; CHECK: RET_ReallyLR

llvm/test/CodeGen/AArch64/GlobalISel/select-gv-with-offset.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ body: |
2525
; LARGE: RET_ReallyLR implicit $x0
2626
; SMALL-LABEL: name: select_gv_with_offset
2727
; SMALL: liveins: $x0
28-
; SMALL: %g:gpr64 = MOVaddr target-flags(aarch64-page) @g + 1, target-flags(aarch64-pageoff, aarch64-nc) @g + 1
28+
; SMALL: %g:gpr64common = MOVaddr target-flags(aarch64-page) @g + 1, target-flags(aarch64-pageoff, aarch64-nc) @g + 1
2929
; SMALL: $x0 = COPY %g
3030
; SMALL: RET_ReallyLR implicit $x0
3131
; TINY-LABEL: name: select_gv_with_offset

llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ body: |
3030
; CHECK: Bcc 8, %bb.3, implicit $nzcv
3131
; CHECK: bb.1:
3232
; CHECK: successors: %bb.2(0x40000000), %bb.3(0x40000000)
33-
; CHECK: [[MOVaddrJT:%[0-9]+]]:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
33+
; CHECK: [[MOVaddrJT:%[0-9]+]]:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
3434
; CHECK: early-clobber %6:gpr64, early-clobber %7:gpr64sp = JumpTableDest32 [[MOVaddrJT]], [[SUBREG_TO_REG]], %jump-table.0
3535
; CHECK: BR %6
3636
; CHECK: bb.2:

llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ body: |
6565
; CHECK: bb.1.entry:
6666
; CHECK: successors: %bb.3(0x2aaaaaab), %bb.4(0x2aaaaaab), %bb.2(0x2aaaaaab)
6767
; CHECK: [[COPY2:%[0-9]+]]:gpr32 = COPY $wzr
68-
; CHECK: [[MOVaddrJT:%[0-9]+]]:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
68+
; CHECK: [[MOVaddrJT:%[0-9]+]]:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
6969
; CHECK: early-clobber %18:gpr64, early-clobber %19:gpr64sp = JumpTableDest32 [[MOVaddrJT]], [[SUBREG_TO_REG]], %jump-table.0
7070
; CHECK: BR %18
7171
; CHECK: bb.2.sw.bb:

llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ registers:
7575
- { id: 0, class: gpr }
7676

7777
# CHECK: body:
78-
# LINUX-DEFAULT: %0:gpr64 = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
78+
# LINUX-DEFAULT: %0:gpr64common = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
7979
body: |
8080
bb.0:
8181
%0(p0) = G_GLOBAL_VALUE @var_local
@@ -91,7 +91,7 @@ registers:
9191
- { id: 0, class: gpr }
9292

9393
# CHECK: body:
94-
# LINUX-DEFAULT: %0:gpr64 = MOVaddr target-flags(aarch64-page) @var_got, target-flags(aarch64-pageoff, aarch64-nc) @var_got
94+
# LINUX-DEFAULT: %0:gpr64common = MOVaddr target-flags(aarch64-page) @var_got, target-flags(aarch64-pageoff, aarch64-nc) @var_got
9595
body: |
9696
bb.0:
9797
%0(p0) = G_GLOBAL_VALUE @var_got

llvm/test/CodeGen/AArch64/GlobalISel/select.mir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ registers:
7676
- { id: 0, class: gpr }
7777

7878
# CHECK: body:
79-
# IOS: %0:gpr64 = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
80-
# LINUX-PIC: %0:gpr64 = LOADgot target-flags(aarch64-got) @var_local
79+
# IOS: %0:gpr64common = MOVaddr target-flags(aarch64-page) @var_local, target-flags(aarch64-pageoff, aarch64-nc) @var_local
80+
# LINUX-PIC: %0:gpr64common = LOADgot target-flags(aarch64-got) @var_local
8181
body: |
8282
bb.0:
8383
%0(p0) = G_GLOBAL_VALUE @var_local
@@ -93,8 +93,8 @@ registers:
9393
- { id: 0, class: gpr }
9494

9595
# CHECK: body:
96-
# IOS: %0:gpr64 = LOADgot target-flags(aarch64-got) @var_got
97-
# LINUX-PIC: %0:gpr64 = LOADgot target-flags(aarch64-got) @var_got
96+
# IOS: %0:gpr64common = LOADgot target-flags(aarch64-got) @var_got
97+
# LINUX-PIC: %0:gpr64common = LOADgot target-flags(aarch64-got) @var_got
9898
body: |
9999
bb.0:
100100
%0(p0) = G_GLOBAL_VALUE @var_got

llvm/test/CodeGen/AArch64/elim-dead-mi.mir

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@
1313
name: main
1414
tracksRegLiveness: true
1515
registers:
16-
- { id: 0, class: gpr64, preferred-register: '' }
16+
- { id: 0, class: gpr64common, preferred-register: '' }
1717
- { id: 1, class: gpr64common, preferred-register: '' }
1818
- { id: 2, class: gpr64, preferred-register: '' }
1919
- { id: 3, class: gpr64common, preferred-register: '' }
2020
- { id: 4, class: gpr32, preferred-register: '' }
2121
- { id: 5, class: gpr32all, preferred-register: '' }
22-
- { id: 6, class: gpr64, preferred-register: '' }
22+
- { id: 6, class: gpr64common, preferred-register: '' }
2323
body: |
2424
bb.0:
2525
successors: %bb.4(0x30000000), %bb.5(0x50000000)
2626
27-
%0:gpr64 = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
27+
%0:gpr64common = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
2828
CBZX killed %0, %bb.4
2929
B %bb.5
3030
@@ -55,7 +55,7 @@ body: |
5555
bb.5:
5656
successors: %bb.1(0x80000000)
5757
; CHECK: bb.5
58-
; CHECK-NOT: %6:gpr64 = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
59-
%6:gpr64 = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
58+
; CHECK-NOT: %6:gpr64common = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
59+
%6:gpr64common = MOVaddr target-flags(aarch64-page) @c, target-flags(aarch64-pageoff, aarch64-nc) @c
6060
B %bb.1
6161
...

llvm/test/CodeGen/AArch64/loop-sink.mir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ registers:
274274
- { id: 17, class: gpr32, preferred-register: '' }
275275
- { id: 18, class: gpr32sp, preferred-register: '' }
276276
- { id: 19, class: gpr32, preferred-register: '' }
277-
- { id: 20, class: gpr64, preferred-register: '' }
277+
- { id: 20, class: gpr64common, preferred-register: '' }
278278
- { id: 21, class: gpr64, preferred-register: '' }
279279
- { id: 22, class: gpr64sp, preferred-register: '' }
280280
- { id: 23, class: gpr64sp, preferred-register: '' }
@@ -338,7 +338,7 @@ body: |
338338
; CHECK: [[COPY6:%[0-9]+]]:gpr64all = COPY [[ADDXri4]]
339339
; CHECK: [[ADDXri5:%[0-9]+]]:gpr64sp = ADDXri [[COPY1]], 1, 0
340340
; CHECK: [[COPY7:%[0-9]+]]:gpr64all = COPY [[ADDXri5]]
341-
; CHECK: [[MOVaddrJT:%[0-9]+]]:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
341+
; CHECK: [[MOVaddrJT:%[0-9]+]]:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
342342
; CHECK: bb.1..backedge:
343343
; CHECK: successors: %bb.9(0x09249249), %bb.2(0x76db6db7)
344344
; CHECK: [[PHI:%[0-9]+]]:gpr64sp = PHI [[COPY7]], %bb.0, %7, %bb.9
@@ -415,7 +415,7 @@ body: |
415415
%4:gpr64all = COPY %14
416416
%15:gpr64sp = ADDXri %8, 1, 0
417417
%5:gpr64all = COPY %15
418-
%20:gpr64 = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
418+
%20:gpr64common = MOVaddrJT target-flags(aarch64-page) %jump-table.0, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0
419419
420420
bb.1..backedge:
421421
successors: %bb.8(0x09249249), %bb.9(0x76db6db7)

0 commit comments

Comments
 (0)