Skip to content

Commit 0ba456f

Browse files
authored
[Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (#138391)
There're four possible formats to refer a register in inline assembly, 1. Numeric name without dollar sign ("f0") 2. Numeric name with dollar sign ("$f0") 3. ABI name without dollar sign ("fa0") 4. ABI name with dollar sign ("$fa0") LoongArch GCC accepts 1 and 2 for FPRs before r15-8284[1] and all these formats after the chagne. But Clang supports only 2 and 4 for FPRs. The inconsistency has caused compatibility issues, such as QEMU's case[2]. This patch follows 0bbf3dd ("[Clang][LoongArch] Add GPR alias handling without `$` prefix") and accepts FPRs without dollar sign prefixes as well to keep aligned with GCC, avoiding future compatibility problems. Link: https://gcc.gnu.org/cgit/gcc/commit/?id=d0110185eb78f14a8e485f410bee237c9c71548d [1] Link: https://lore.kernel.org/qemu-devel/20250314033150.53268-3-ziyao@disroot.org/ [2]
1 parent e34e021 commit 0ba456f

File tree

3 files changed

+86
-57
lines changed

3 files changed

+86
-57
lines changed

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,38 +81,46 @@ LoongArchTargetInfo::getGCCRegAliases() const {
8181
{{"s6", "$s6", "r29"}, "$r29"},
8282
{{"s7", "$s7", "r30"}, "$r30"},
8383
{{"s8", "$s8", "r31"}, "$r31"},
84-
{{"$fa0"}, "$f0"},
85-
{{"$fa1"}, "$f1"},
86-
{{"$fa2"}, "$f2"},
87-
{{"$fa3"}, "$f3"},
88-
{{"$fa4"}, "$f4"},
89-
{{"$fa5"}, "$f5"},
90-
{{"$fa6"}, "$f6"},
91-
{{"$fa7"}, "$f7"},
92-
{{"$ft0"}, "$f8"},
93-
{{"$ft1"}, "$f9"},
94-
{{"$ft2"}, "$f10"},
95-
{{"$ft3"}, "$f11"},
96-
{{"$ft4"}, "$f12"},
97-
{{"$ft5"}, "$f13"},
98-
{{"$ft6"}, "$f14"},
99-
{{"$ft7"}, "$f15"},
100-
{{"$ft8"}, "$f16"},
101-
{{"$ft9"}, "$f17"},
102-
{{"$ft10"}, "$f18"},
103-
{{"$ft11"}, "$f19"},
104-
{{"$ft12"}, "$f20"},
105-
{{"$ft13"}, "$f21"},
106-
{{"$ft14"}, "$f22"},
107-
{{"$ft15"}, "$f23"},
108-
{{"$fs0"}, "$f24"},
109-
{{"$fs1"}, "$f25"},
110-
{{"$fs2"}, "$f26"},
111-
{{"$fs3"}, "$f27"},
112-
{{"$fs4"}, "$f28"},
113-
{{"$fs5"}, "$f29"},
114-
{{"$fs6"}, "$f30"},
115-
{{"$fs7"}, "$f31"},
84+
{{"fa0", "$fa0", "f0"}, "$f0"},
85+
{{"fa1", "$fa1", "f1"}, "$f1"},
86+
{{"fa2", "$fa2", "f2"}, "$f2"},
87+
{{"fa3", "$fa3", "f3"}, "$f3"},
88+
{{"fa4", "$fa4", "f4"}, "$f4"},
89+
{{"fa5", "$fa5", "f5"}, "$f5"},
90+
{{"fa6", "$fa6", "f6"}, "$f6"},
91+
{{"fa7", "$fa7", "f7"}, "$f7"},
92+
{{"ft0", "$ft0", "f8"}, "$f8"},
93+
{{"ft1", "$ft1", "f9"}, "$f9"},
94+
{{"ft2", "$ft2", "f10"}, "$f10"},
95+
{{"ft3", "$ft3", "f11"}, "$f11"},
96+
{{"ft4", "$ft4", "f12"}, "$f12"},
97+
{{"ft5", "$ft5", "f13"}, "$f13"},
98+
{{"ft6", "$ft6", "f14"}, "$f14"},
99+
{{"ft7", "$ft7", "f15"}, "$f15"},
100+
{{"ft8", "$ft8", "f16"}, "$f16"},
101+
{{"ft9", "$ft9", "f17"}, "$f17"},
102+
{{"ft10", "$ft10", "f18"}, "$f18"},
103+
{{"ft11", "$ft11", "f19"}, "$f19"},
104+
{{"ft12", "$ft12", "f20"}, "$f20"},
105+
{{"ft13", "$ft13", "f21"}, "$f21"},
106+
{{"ft14", "$ft14", "f22"}, "$f22"},
107+
{{"ft15", "$ft15", "f23"}, "$f23"},
108+
{{"fs0", "$fs0", "f24"}, "$f24"},
109+
{{"fs1", "$fs1", "f25"}, "$f25"},
110+
{{"fs2", "$fs2", "f26"}, "$f26"},
111+
{{"fs3", "$fs3", "f27"}, "$f27"},
112+
{{"fs4", "$fs4", "f28"}, "$f28"},
113+
{{"fs5", "$fs5", "f29"}, "$f29"},
114+
{{"fs6", "$fs6", "f30"}, "$f30"},
115+
{{"fs7", "$fs7", "f31"}, "$f31"},
116+
{{"fcc0"}, "$fcc0"},
117+
{{"fcc1"}, "$fcc1"},
118+
{{"fcc2"}, "$fcc2"},
119+
{{"fcc3"}, "$fcc3"},
120+
{{"fcc4"}, "$fcc4"},
121+
{{"fcc5"}, "$fcc5"},
122+
{{"fcc6"}, "$fcc6"},
123+
{{"fcc7"}, "$fcc7"},
116124
};
117125
return llvm::ArrayRef(GCCRegAliases);
118126
}

clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,4 @@ void test(void) {
88
register float a1 asm ("$f32");
99
// CHECK: :[[#@LINE+1]]:24: error: unknown register name '$foo' in asm
1010
register int a2 asm ("$foo");
11-
12-
/// Names not prefixed with '$' are invalid.
13-
14-
// CHECK: :[[#@LINE+1]]:26: error: unknown register name 'f0' in asm
15-
register float a5 asm ("f0");
16-
// CHECK: :[[#@LINE+1]]:26: error: unknown register name 'fa0' in asm
17-
register float a6 asm ("fa0");
18-
// CHECK: :[[#@LINE+1]]:15: error: unknown register name 'fcc0' in asm
19-
asm ("" ::: "fcc0");
2011
}

clang/test/CodeGen/LoongArch/inline-asm-gcc-regs.c

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
/// Check GCC register names and alias can be used in register variable definition.
55

66
// CHECK-LABEL: @test_r0
7-
// CHECK: call void asm sideeffect "", "{$r0}"(i32 undef)
7+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r0}"(i32 undef)
8+
// CHECK-NOT: call void asm sideeffect "", "{$r0}"(i32 undef)
89
void test_r0() {
910
register int a asm ("$r0");
1011
register int b asm ("r0");
@@ -13,7 +14,8 @@ void test_r0() {
1314
}
1415

1516
// CHECK-LABEL: @test_r12
16-
// CHECK: call void asm sideeffect "", "{$r12}"(i32 undef)
17+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r12}"(i32 undef)
18+
// CHECK-NOT: call void asm sideeffect "", "{$r12}"(i32 undef)
1719
void test_r12() {
1820
register int a asm ("$r12");
1921
register int b asm ("r12");
@@ -22,7 +24,8 @@ void test_r12() {
2224
}
2325

2426
// CHECK-LABEL: @test_r31
25-
// CHECK: call void asm sideeffect "", "{$r31}"(i32 undef)
27+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r31}"(i32 undef)
28+
// CHECK-NOT: call void asm sideeffect "", "{$r31}"(i32 undef)
2629
void test_r31() {
2730
register int a asm ("$r31");
2831
register int b asm ("r31");
@@ -31,7 +34,8 @@ void test_r31() {
3134
}
3235

3336
// CHECK-LABEL: @test_zero
34-
// CHECK: call void asm sideeffect "", "{$r0}"(i32 undef)
37+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r0}"(i32 undef)
38+
// CHECK-NOT: call void asm sideeffect "", "{$r0}"(i32 undef)
3539
void test_zero() {
3640
register int a asm ("$zero");
3741
register int b asm ("zero");
@@ -40,7 +44,8 @@ void test_zero() {
4044
}
4145

4246
// CHECK-LABEL: @test_a0
43-
// CHECK: call void asm sideeffect "", "{$r4}"(i32 undef)
47+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r4}"(i32 undef)
48+
// CHECK-NOT: call void asm sideeffect "", "{$r4}"(i32 undef)
4449
void test_a0() {
4550
register int a asm ("$a0");
4651
register int b asm ("a0");
@@ -49,7 +54,8 @@ void test_a0() {
4954
}
5055

5156
// CHECK-LABEL: @test_t1
52-
// CHECK: call void asm sideeffect "", "{$r13}"(i32 undef)
57+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r13}"(i32 undef)
58+
// CHECK-NOT: call void asm sideeffect "", "{$r13}"(i32 undef)
5359
void test_t1() {
5460
register int a asm ("$t1");
5561
register int b asm ("t1");
@@ -58,7 +64,8 @@ void test_t1() {
5864
}
5965

6066
// CHECK-LABEL: @test_fp
61-
// CHECK: call void asm sideeffect "", "{$r22}"(i32 undef)
67+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r22}"(i32 undef)
68+
// CHECK-NOT: call void asm sideeffect "", "{$r22}"(i32 undef)
6269
void test_fp() {
6370
register int a asm ("$fp");
6471
register int b asm ("fp");
@@ -67,7 +74,8 @@ void test_fp() {
6774
}
6875

6976
// CHECK-LABEL: @test_s2
70-
// CHECK: call void asm sideeffect "", "{$r25}"(i32 undef)
77+
// CHECK-COUNT-2: call void asm sideeffect "", "{$r25}"(i32 undef)
78+
// CHECK-NOT: call void asm sideeffect "", "{$r25}"(i32 undef)
7179
void test_s2() {
7280
register int a asm ("$s2");
7381
register int b asm ("s2");
@@ -76,51 +84,73 @@ void test_s2() {
7684
}
7785

7886
// CHECK-LABEL: @test_f0
79-
// CHECK: call void asm sideeffect "", "{$f0}"(float undef)
87+
// CHECK-COUNT-2: call void asm sideeffect "", "{$f0}"(float undef)
88+
// CHECK-NOT: call void asm sideeffect "", "{$f0}"(float undef)
8089
void test_f0() {
8190
register float a asm ("$f0");
91+
register float b asm ("f0");
8292
asm ("" :: "f" (a));
93+
asm ("" :: "f" (b));
8394
}
8495

8596
// CHECK-LABEL: @test_f14
86-
// CHECK: call void asm sideeffect "", "{$f14}"(float undef)
97+
// CHECK-COUNT-2: call void asm sideeffect "", "{$f14}"(float undef)
98+
// CHECK-NOT: call void asm sideeffect "", "{$f14}"(float undef)
8799
void test_f14() {
88100
register float a asm ("$f14");
101+
register float b asm ("f14");
89102
asm ("" :: "f" (a));
103+
asm ("" :: "f" (b));
90104
}
91105

92106
// CHECK-LABEL: @test_f31
93-
// CHECK: call void asm sideeffect "", "{$f31}"(float undef)
107+
// CHECK-COUNT-2: call void asm sideeffect "", "{$f31}"(float undef)
108+
// CHECK-NOT: call void asm sideeffect "", "{$f31}"(float undef)
94109
void test_f31() {
95110
register float a asm ("$f31");
111+
register float b asm ("f31");
96112
asm ("" :: "f" (a));
113+
asm ("" :: "f" (b));
97114
}
98115

99116
// CHECK-LABEL: @test_fa0
100-
// CHECK: call void asm sideeffect "", "{$f0}"(float undef)
117+
// CHECK-COUNT-2: call void asm sideeffect "", "{$f0}"(float undef)
118+
// CHECK-NOT: call void asm sideeffect "", "{$f0}"(float undef)
101119
void test_fa0() {
102120
register float a asm ("$fa0");
121+
register float b asm ("fa0");
103122
asm ("" :: "f" (a));
123+
asm ("" :: "f" (b));
104124
}
105125

106126
// CHECK-LABEL: @test_ft1
107-
// CHECK: call void asm sideeffect "", "{$f9}"(float undef)
127+
// CHECK-COUNT-2: call void asm sideeffect "", "{$f9}"(float undef)
128+
// CHECK-NOT: call void asm sideeffect "", "{$f9}"(float undef)
108129
void test_ft1() {
109130
register float a asm ("$ft1");
131+
register float b asm ("ft1");
110132
asm ("" :: "f" (a));
133+
asm ("" :: "f" (b));
111134
}
112135

113136
// CHECK-LABEL: @test_fs2
114-
// CHECK: call void asm sideeffect "", "{$f26}"(float undef)
137+
// CHECK-COUNT-2: call void asm sideeffect "", "{$f26}"(float undef)
138+
// CHECK-NOT: call void asm sideeffect "", "{$f26}"(float undef)
115139
void test_fs2() {
116140
register float a asm ("$fs2");
141+
register float b asm ("fs2");
117142
asm ("" :: "f" (a));
143+
asm ("" :: "f" (b));
118144
}
119145

120146
// CHECK-LABEL: @test_fcc
121-
// CHECK: call void asm sideeffect "", "~{$fcc0}"()
122-
// CHECK: call void asm sideeffect "", "~{$fcc7}"()
147+
// CHECK-COUNT-2: call void asm sideeffect "", "~{$fcc0}"()
148+
// CHECK-NOT: call void asm sideeffect "", "~{$fcc0}"()
149+
// CHECK-COUNT-2: call void asm sideeffect "", "~{$fcc7}"()
150+
// CHECK-NOT: call void asm sideeffect "", "~{$fcc7}"()
123151
void test_fcc() {
124152
asm ("" ::: "$fcc0");
153+
asm ("" ::: "fcc0");
125154
asm ("" ::: "$fcc7");
155+
asm ("" ::: "fcc7");
126156
}

0 commit comments

Comments
 (0)