-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[LoongArch] Incorrect register allocation for [G]CSRXCHG
- rj must not be R0 ro R1
#140842
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
Labels
Comments
@llvm/issue-subscribers-backend-loongarch Author: hev (heiher)
In the LoongArch target, the `{G}CSRXCHG` instruction has a special encoding constraint:
If the Currently, LLVM’s register allocator may assign R0 or R1 to the Reproduce case: declare i64 @<!-- -->llvm.loongarch.csrxchg.d(i64, i64, i32 immarg);
define dso_local i64 @<!-- -->csrxchg() {
entry:
%0 = tail call i64 asm sideeffect "", "=r,r,i,{$r4},{$r5},{$r6},{$r7},{$r8},{$r9},{$r10},{$r11},{$r12},{$r13},{$r14},{$r15},{$r16},{$r17},{$r18},{$r19},{$r20},{$r23},{$r24},{$r25},{$r26},{$r27},{$r28},{$r29},{$r30},{$r31},0,~{memory}"(i32 4, i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i64 0)
%1 = tail call i64 @<!-- -->llvm.loongarch.csrxchg.d(i64 %0, i64 4, i32 0)
%2 = tail call i64 asm sideeffect "", "=r,r,i,{$r4},{$r5},{$r6},{$r7},{$r8},{$r9},{$r10},{$r11},{$r12},{$r13},{$r14},{$r15},{$r16},{$r17},{$r18},{$r19},{$r20},{$r23},{$r24},{$r25},{$r26},{$r27},{$r28},{$r29},{$r30},{$r31},0,~{memory}"(i32 4, i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i64 %1)
ret i64 %2
} |
heiher
added a commit
to heiher/llvm-project
that referenced
this issue
May 21, 2025
The {G}CSRXCHG instruction must not use R0 or R1 as the rj operand, as encoding rj as 0 or 1 will be interpreted as {G}CSRRD OR {G}CSRWR, respectively, rather than {G}CSRXCHG. This patch introduces a new register class `GPRNoR0R1` and updates the {G}CSRXCHG instruction definition to use it for the rj operand, ensuring the register allocator avoids assigning R0 or R1. Fixes llvm#140842
{G}CSRXCHG
- rj must not be R0 ro R1[G]CSRXCHG
- rj must not be R0 ro R1
heiher
added a commit
that referenced
this issue
May 22, 2025
…40862) The `[G]CSRXCHG` instruction must not use R0 or R1 as the `rj` operand, as encoding `rj` as 0 or 1 will be interpreted as `[G]CSRRD` OR `[G]CSRWR`, respectively, rather than `[G]CSRXCHG`. This patch introduces a new register class `GPRNoR0R1` and updates the `[G]CSRXCHG` instruction definition to use it for the `rj` operand, ensuring the register allocator avoids assigning R0 or R1. Fixes #140842
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In the LoongArch target, the
[G]CSRXCHG
instruction has a special encoding constraint:If the
rj
operand is assigned to register R0 or R1, the instruction encoding will be interpreted as[G]CSRRD
or[G]CSRWR
respectively, not[G]CSRXCHG
.Currently, LLVM’s register allocator may assign R0 or R1 to the
rj
operand of a[G]CSRXCHG
instruction, which leads to incorrect code generation and unintended semantics.Reproduce case:
The text was updated successfully, but these errors were encountered: