[Aarch64] Correct register class for pseudo instructions
authorJameson Nash <vtjnash@gmail.com>
Thu, 9 Sep 2021 17:44:38 +0000 (13:44 -0400)
committerJameson Nash <vtjnash@gmail.com>
Thu, 9 Sep 2021 18:31:49 +0000 (14:31 -0400)
commite20f69f612dd678f68473e3f111ee891f7d2d108
tree83d2c8af3ad5d0ed9ec03f04f60cebadb7612c63
parentd99a83b4e5fe1fd799c8c54772dc2372ea4d3e1b
[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
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