[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