[llvm] 050dad5 - [AArch64][GISel] constrain regclass for 128->64 copy

Tomas Matheson via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 30 03:03:10 PDT 2022


Author: Tomas Matheson
Date: 2022-08-30T11:02:51+01:00
New Revision: 050dad57f7e1a00933cb5bf31ffd671680c03ee3

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

LOG: [AArch64][GISel] constrain regclass for 128->64 copy

When selecting G_EXTRACT to COPY for extracting a 64-bit GPR from
a 128-bit register pair (XSeqPair) we know enough to constrain the
destination register class to gpr64. Without this it may have only
a register bank and some copy elimination code would assert while
assuming that a register class existed.

The register class has to be set explicitly because we might hit the
COPY -> COPY case where register class can't be inferred.

This would cause the following to crash in selection, where the store
is commented (otherwise the store constrains the register class):

  define dso_local i128 @load_atomic_i128_unordered(i128* %p) {
    %pair = cmpxchg i128* %p, i128 0, i128 0 acquire acquire
    %val = extractvalue { i128, i1 } %pair, 0
    ; store i128 %val, i128* %p
    ret i128 %val
  }

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

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
    llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index ae6d11717ab49..d4cdf2140d7db 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2679,8 +2679,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
       assert(SrcRB.getID() == DstRB.getID() && "Wrong extract regbank!");
 
       if (SrcRB.getID() == AArch64::GPRRegBankID) {
-        MIB.buildInstr(TargetOpcode::COPY, {DstReg}, {})
-            .addUse(SrcReg, 0, Offset == 0 ? AArch64::sube64 : AArch64::subo64);
+        auto NewI =
+            MIB.buildInstr(TargetOpcode::COPY, {DstReg}, {})
+                .addUse(SrcReg, 0,
+                        Offset == 0 ? AArch64::sube64 : AArch64::subo64);
+        constrainOperandRegClass(MF, TRI, MRI, TII, RBI, *NewI,
+                                 AArch64::GPR64RegClass, NewI->getOperand(0));
         I.eraseFromParent();
         return true;
       }

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
index 5b81be232ec03..556c9ece831a2 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
@@ -415,3 +415,74 @@ define void @atomic_load_relaxed(i64, i64, i128* %p, i128* %p2) {
     store i128 %r, i128* %p2
     ret void
 }
+
+define i128 @val_compare_and_swap_return(i128* %p, i128 %oldval, i128 %newval) {
+; CHECK-LLSC-O1-LABEL: val_compare_and_swap_return:
+; CHECK-LLSC-O1:       // %bb.0:
+; CHECK-LLSC-O1-NEXT:  .LBB5_1: // =>This Inner Loop Header: Depth=1
+; CHECK-LLSC-O1-NEXT:    ldaxp x8, x1, [x0]
+; CHECK-LLSC-O1-NEXT:    cmp x8, x2
+; CHECK-LLSC-O1-NEXT:    cset w9, ne
+; CHECK-LLSC-O1-NEXT:    cmp x1, x3
+; CHECK-LLSC-O1-NEXT:    cinc w9, w9, ne
+; CHECK-LLSC-O1-NEXT:    cbz w9, .LBB5_3
+; CHECK-LLSC-O1-NEXT:  // %bb.2: // in Loop: Header=BB5_1 Depth=1
+; CHECK-LLSC-O1-NEXT:    stxp w9, x8, x1, [x0]
+; CHECK-LLSC-O1-NEXT:    cbnz w9, .LBB5_1
+; CHECK-LLSC-O1-NEXT:    b .LBB5_4
+; CHECK-LLSC-O1-NEXT:  .LBB5_3: // in Loop: Header=BB5_1 Depth=1
+; CHECK-LLSC-O1-NEXT:    stxp w9, x4, x5, [x0]
+; CHECK-LLSC-O1-NEXT:    cbnz w9, .LBB5_1
+; CHECK-LLSC-O1-NEXT:  .LBB5_4:
+; CHECK-LLSC-O1-NEXT:    mov x0, x8
+; CHECK-LLSC-O1-NEXT:    ret
+;
+; CHECK-CAS-O1-LABEL: val_compare_and_swap_return:
+; CHECK-CAS-O1:       // %bb.0:
+; CHECK-CAS-O1-NEXT:    // kill: def $x2 killed $x2 killed $x2_x3 def $x2_x3
+; CHECK-CAS-O1-NEXT:    // kill: def $x4 killed $x4 killed $x4_x5 def $x4_x5
+; CHECK-CAS-O1-NEXT:    // kill: def $x3 killed $x3 killed $x2_x3 def $x2_x3
+; CHECK-CAS-O1-NEXT:    // kill: def $x5 killed $x5 killed $x4_x5 def $x4_x5
+; CHECK-CAS-O1-NEXT:    caspa x2, x3, x4, x5, [x0]
+; CHECK-CAS-O1-NEXT:    mov x0, x2
+; CHECK-CAS-O1-NEXT:    mov x1, x3
+; CHECK-CAS-O1-NEXT:    ret
+;
+; CHECK-LLSC-O0-LABEL: val_compare_and_swap_return:
+; CHECK-LLSC-O0:       // %bb.0:
+; CHECK-LLSC-O0-NEXT:    mov x9, x0
+; CHECK-LLSC-O0-NEXT:  .LBB5_1: // =>This Inner Loop Header: Depth=1
+; CHECK-LLSC-O0-NEXT:    ldaxp x0, x1, [x9]
+; CHECK-LLSC-O0-NEXT:    cmp x0, x2
+; CHECK-LLSC-O0-NEXT:    cset w8, ne
+; CHECK-LLSC-O0-NEXT:    cmp x1, x3
+; CHECK-LLSC-O0-NEXT:    cinc w8, w8, ne
+; CHECK-LLSC-O0-NEXT:    cbnz w8, .LBB5_3
+; CHECK-LLSC-O0-NEXT:  // %bb.2: // in Loop: Header=BB5_1 Depth=1
+; CHECK-LLSC-O0-NEXT:    stxp w8, x4, x5, [x9]
+; CHECK-LLSC-O0-NEXT:    cbnz w8, .LBB5_1
+; CHECK-LLSC-O0-NEXT:    b .LBB5_4
+; CHECK-LLSC-O0-NEXT:  .LBB5_3: // in Loop: Header=BB5_1 Depth=1
+; CHECK-LLSC-O0-NEXT:    stxp w8, x0, x1, [x9]
+; CHECK-LLSC-O0-NEXT:    cbnz w8, .LBB5_1
+; CHECK-LLSC-O0-NEXT:  .LBB5_4:
+; CHECK-LLSC-O0-NEXT:    ret
+;
+; CHECK-CAS-O0-LABEL: val_compare_and_swap_return:
+; CHECK-CAS-O0:       // %bb.0:
+; CHECK-CAS-O0-NEXT:    mov x8, x0
+; CHECK-CAS-O0-NEXT:    mov x1, x3
+; CHECK-CAS-O0-NEXT:    mov x0, x4
+; CHECK-CAS-O0-NEXT:    // kill: def $x2 killed $x2 def $x2_x3
+; CHECK-CAS-O0-NEXT:    mov x3, x1
+; CHECK-CAS-O0-NEXT:    // kill: def $x0 killed $x0 def $x0_x1
+; CHECK-CAS-O0-NEXT:    mov x1, x5
+; CHECK-CAS-O0-NEXT:    caspa x2, x3, x0, x1, [x8]
+; CHECK-CAS-O0-NEXT:    mov x0, x2
+; CHECK-CAS-O0-NEXT:    mov x1, x3
+; CHECK-CAS-O0-NEXT:    ret
+
+  %pair = cmpxchg i128* %p, i128 %oldval, i128 %newval acquire acquire
+  %val = extractvalue { i128, i1 } %pair, 0
+  ret i128 %val
+}


        


More information about the llvm-commits mailing list