[llvm] b134c62 - [AArch64] Fix creation of invalid instructions with XZR register
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 8 05:17:17 PST 2023
Author: David Green
Date: 2023-02-08T13:17:10Z
New Revision: b134c62facef01dabf901ee6a6283e3b0fb3a249
URL: https://github.com/llvm/llvm-project/commit/b134c62facef01dabf901ee6a6283e3b0fb3a249
DIFF: https://github.com/llvm/llvm-project/commit/b134c62facef01dabf901ee6a6283e3b0fb3a249.diff
LOG: [AArch64] Fix creation of invalid instructions with XZR register
A combination of GlobalISel and MachineCombiner can end up creating
`SUB xrz, (MOVI -2105098)` instructions which have not been constant
folded. The AArch64MIPeepholeOpt pass will then attempt to create
`ADD xzr, 513, lsl 12`, which is not a valid instruction. This adds
a bail out of the transform if the register is xzr/wzr.
Fixes #60528
Differential Revision: https://reviews.llvm.org/D143475
Added:
Modified:
llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
llvm/test/CodeGen/AArch64/addsub-24bit-imm.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp b/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
index 4c495c203a808..6ff5ced2f3307 100644
--- a/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MIPeepholeOpt.cpp
@@ -323,17 +323,24 @@ bool AArch64MIPeepholeOpt::visitADDSUB(
unsigned PosOpc, unsigned NegOpc, MachineInstr &MI) {
// Try below transformation.
//
- // MOVi32imm + ADDWrr ==> ADDWri + ADDWri
- // MOVi64imm + ADDXrr ==> ADDXri + ADDXri
+ // ADDWrr X, MOVi32imm ==> ADDWri + ADDWri
+ // ADDXrr X, MOVi64imm ==> ADDXri + ADDXri
//
- // MOVi32imm + SUBWrr ==> SUBWri + SUBWri
- // MOVi64imm + SUBXrr ==> SUBXri + SUBXri
+ // SUBWrr X, MOVi32imm ==> SUBWri + SUBWri
+ // SUBXrr X, MOVi64imm ==> SUBXri + SUBXri
//
// The mov pseudo instruction could be expanded to multiple mov instructions
// later. Let's try to split the constant operand of mov instruction into two
// legal add/sub immediates. It makes only two ADD/SUB instructions intead of
// multiple `mov` + `and/sub` instructions.
+ // We can sometimes have ADDWrr WZR, MULi32imm that have not been constant
+ // folded. Make sure that we don't generate invalid instructions that use XZR
+ // in those cases.
+ if (MI.getOperand(1).getReg() == AArch64::XZR ||
+ MI.getOperand(1).getReg() == AArch64::WZR)
+ return false;
+
return splitTwoPartImm<T>(
MI,
[PosOpc, NegOpc](T Imm, unsigned RegSize, T &Imm0,
@@ -365,6 +372,11 @@ bool AArch64MIPeepholeOpt::visitADDSSUBS(
OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI) {
// Try the same transformation as ADDSUB but with additional requirement
// that the condition code usages are only for Equal and Not Equal
+
+ if (MI.getOperand(1).getReg() == AArch64::XZR ||
+ MI.getOperand(1).getReg() == AArch64::WZR)
+ return false;
+
return splitTwoPartImm<T>(
MI,
[PosOpcs, NegOpcs, &MI, &TRI = TRI,
diff --git a/llvm/test/CodeGen/AArch64/addsub-24bit-imm.mir b/llvm/test/CodeGen/AArch64/addsub-24bit-imm.mir
index b114e617cbd87..98a73bdd93203 100644
--- a/llvm/test/CodeGen/AArch64/addsub-24bit-imm.mir
+++ b/llvm/test/CodeGen/AArch64/addsub-24bit-imm.mir
@@ -10,7 +10,9 @@ body: |
bb.0.entry:
liveins: $w0
; CHECK-LABEL: name: addi
- ; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32common = COPY $w0
; CHECK-NEXT: [[ADDWri:%[0-9]+]]:gpr32sp = ADDWri [[COPY]], 273, 12
; CHECK-NEXT: [[ADDWri1:%[0-9]+]]:gpr32common = ADDWri [[ADDWri]], 3549, 0
; CHECK-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[ADDWri1]], 28, 31
@@ -29,7 +31,9 @@ body: |
bb.0.entry:
liveins: $x0
; CHECK-LABEL: name: addl
- ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY]], 273, 12
; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64common = ADDXri [[ADDXri]], 3549, 0
; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64 = UBFMXri [[ADDXri1]], 28, 31
@@ -49,7 +53,9 @@ body: |
bb.0.entry:
liveins: $x0
; CHECK-LABEL: name: addl_negate
- ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
; CHECK-NEXT: [[SUBXri:%[0-9]+]]:gpr64sp = SUBXri [[COPY]], 273, 12
; CHECK-NEXT: [[SUBXri1:%[0-9]+]]:gpr64common = SUBXri [[SUBXri]], 3549, 0
; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64 = UBFMXri [[SUBXri1]], 28, 31
@@ -61,3 +67,87 @@ body: |
%3:gpr64 = UBFMXri %2, 28, 31
$x0 = COPY %3
RET_ReallyLR implicit $x0
+...
+---
+name: add_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: add_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr $xzr, [[MOVi64imm]]
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[ADDXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = ADDXrr $xzr, %2
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
+...
+---
+name: sub_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: sub_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[SUBXrr:%[0-9]+]]:gpr64common = SUBXrr $xzr, [[MOVi64imm]]
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[SUBXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = SUBXrr $xzr, %2
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
+...
+---
+name: adds_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: adds_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[ADDSXrr:%[0-9]+]]:gpr64common = ADDSXrr $xzr, [[MOVi64imm]], implicit-def $nzcv
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[ADDSXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = ADDSXrr $xzr, %2, implicit-def $nzcv
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
+...
+---
+name: subs_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: subs_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64common = SUBSXrr $xzr, [[MOVi64imm]], implicit-def $nzcv
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[SUBSXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = SUBSXrr $xzr, %2, implicit-def $nzcv
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
More information about the llvm-commits
mailing list