[PATCH] D132665: [GISel] constrain regclas for 128->64 copy
Tomas Matheson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 25 08:19:18 PDT 2022
tmatheson created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
tmatheson requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
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
}
Change-Id: I0e875e7043352bf1c2c6233d64bfccf62650adba
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D132665
Files:
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
Index: llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
===================================================================
--- llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
+++ llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
@@ -415,3 +415,74 @@
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
+}
Index: llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
===================================================================
--- llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2679,8 +2679,12 @@
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;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132665.455595.patch
Type: text/x-patch
Size: 4308 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220825/caf0263e/attachment.bin>
More information about the llvm-commits
mailing list