-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LoongArch][NFC] Fix the operand constraint of AMCAS instructions #114508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-loongarch Author: WÁNG Xuěruì (xen0n) ChangesThe While at it, restore vertical alignment for the definition lines. Suggested-by: tangaac <[email protected]> Full diff: https://github.com/llvm/llvm-project/pull/114508.diff 2 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index b4b19caed8999e..7e285f0facb2dd 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -1562,7 +1562,8 @@ unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
unsigned Opc = Inst.getOpcode();
switch (Opc) {
default:
- if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
+ if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W &&
+ !(Opc >= LoongArch::AMCAS_B && Opc <= LoongArch::AMCAS__DB_W)) {
MCRegister Rd = Inst.getOperand(0).getReg();
MCRegister Rk = Inst.getOperand(1).getReg();
MCRegister Rj = Inst.getOperand(2).getReg();
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index ccdd5165728231..8a9316f1133c9b 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -715,6 +715,11 @@ class AM_3R<bits<32> op>
: Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj),
"$rd, $rk, $rj">;
+let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "$rd = $rd_wb" in
+class AMCAS_3R<bits<32> op>
+ : Fmt3R<op, (outs GPR:$rd_wb), (ins GPR:$rd, GPR:$rk, GPRMemAtomic:$rj),
+ "$rd, $rk, $rj">;
+
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
class LLBase<bits<32> op>
: Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14),
@@ -1024,14 +1029,14 @@ def AMMAX__DB_WU : AM_3R<0x38700000>;
def AMMAX__DB_DU : AM_3R<0x38708000>;
def AMMIN__DB_WU : AM_3R<0x38710000>;
def AMMIN__DB_DU : AM_3R<0x38718000>;
-def AMCAS_B : AM_3R<0x38580000>;
-def AMCAS_H : AM_3R<0x38588000>;
-def AMCAS_W : AM_3R<0x38590000>;
-def AMCAS_D : AM_3R<0x38598000>;
-def AMCAS__DB_B : AM_3R<0x385a0000>;
-def AMCAS__DB_H : AM_3R<0x385a8000>;
-def AMCAS__DB_W : AM_3R<0x385b0000>;
-def AMCAS__DB_D : AM_3R<0x385b8000>;
+def AMCAS_B : AMCAS_3R<0x38580000>;
+def AMCAS_H : AMCAS_3R<0x38588000>;
+def AMCAS_W : AMCAS_3R<0x38590000>;
+def AMCAS_D : AMCAS_3R<0x38598000>;
+def AMCAS__DB_B : AMCAS_3R<0x385a0000>;
+def AMCAS__DB_H : AMCAS_3R<0x385a8000>;
+def AMCAS__DB_W : AMCAS_3R<0x385b0000>;
+def AMCAS__DB_D : AMCAS_3R<0x385b8000>;
def LL_D : LLBase<0x22000000>;
def SC_D : SCBase<0x23000000>;
def SC_Q : SCBase_128<0x38570000>;
|
b62ea14
to
e20d353
Compare
AMADD_B, AMXOR__DB_D, AMXOR_DB_W escape from the check. From the inc file, it should be Opc >= LoongArch::AMADD_B && Opc <= LoongArch::AMXOR_DB_W |
Then it's a functional change. As I already plan to fix the root cause of the problem once and for all in #114398 I'm not going to temporarily fix it here. |
e20d353
to
85dec17
Compare
Turns out the TableGen change actually caused the test to fail... perfect show of how fragile the original implementation was. I've minimally fixed it and the CI should be green now. |
9a54730
to
f925724
Compare
f925724
to
830b8f5
Compare
The `rd` operand of AMCAS instructions is both read and written, because of the nature of compare-and-swap operations, but currently it is not declared as such. Fix it for upcoming codegen enablement changes. In order to do that, a piece of LoongArchAsmParser logic that relied on TableGen-erated enum variants being ordered in a specific way needs updating; this will be addressed in a following refactor. No functional change intended. While at it, restore vertical alignment for the definition lines. Suggested-by: tangaac <[email protected]> Link: llvm#114398 (comment)
830b8f5
to
f0d7771
Compare
…114398) Depends on #114508 The LoongArch Reference Manual says that the 3-register atomic memory operations cannot have their rd equal to either rj or rk [^1], and both GNU as and LLVM IAS enforce the constraint for non-zero rd. However, currently LoongArch AsmParser is checking for the opcode with a direct numerical comparison on the opcode, which is enum-typed: the fact that all AMO insns have adjacent numerical values is merely a coincidence, and it is better to not rely on the current TableGen implementation behavior. Instead, start to leverage the target-specific flags field of MCInstrDesc, and record the constraint with TableGen, so we can stop treating the opcode value as number. In doing so, we also have to mark whether the instruction is AMCAS, because the operand index of rj and rk for the AMCAS instructions is different. While documenting the new flag, it was found that v1.10 of the Manual did not specify the similar constraint for the AMCAS instructions. Experiments were done on a Loongson 3A6000 (LA664 uarch) and it turned out that at least AMCAS will still signal INE with `rd == rj`. The `rd == rk` case should be a no-op according to the semantics, but as it is meaningless to perform CAS with the "old value" same as the "new value", it is not worth special-casing. So the current behavior of also enforcing the constraint for AMCAS is kept. [^1]: if `rd == rj` an INE would be signaled; if `rd == rk` it is UB.
The
rd
operand of AMCAS instructions is both read and written, because of the nature of compare-and-swap operations, but currently it is not declared as such. Fix it for upcoming codegen enablement changes. In order to do that, a piece of LoongArchAsmParser logic that relied on TableGen-erated enum variants being ordered in a specific way needs updating; this will be addressed in a following refactor. No functional change intended.While at it, restore vertical alignment for the definition lines.
Suggested-by: tangaac [email protected]
Link: #114398 (comment)