33// RUN: FileCheck %s --check-prefix=CHECK-X86
44// RUN: %clang_cc1 -triple ppc64le-linux-gnu -emit-llvm -o - %s | FileCheck %s \
55// RUN: --check-prefix=CHECK-PPC
6-
7- #ifndef __PPC__
6+ // RUN: %clang_cc1 -triple riscv32-linux-gnu -emit-llvm -o - %s | FileCheck %s \
7+ // RUN: --check-prefix=CHECK-RV32
8+ // RUN: %clang_cc1 -triple riscv64-linux-gnu -emit-llvm -o - %s | FileCheck %s \
9+ // RUN: --check-prefix=CHECK-RV64
10+ #ifdef __x86_64__
811
912// Test that we have the structure definition, the gep offsets, the name of the
1013// global, the bit grab, and the icmp correct.
@@ -101,8 +104,10 @@ int v3() { return __builtin_cpu_supports("x86-64-v3"); }
101104// CHECK-X86-NEXT: ret i32 [[CONV]]
102105//
103106int v4 () { return __builtin_cpu_supports ("x86-64-v4" ); }
104- #else
105- // CHECK-PPC-LABEL: define dso_local signext i32 @test(
107+ #endif
108+
109+ #ifdef __PPC__
110+ // CHECK-PPC-LABEL: define dso_local signext i32 @test_ppc(
106111// CHECK-PPC-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
107112// CHECK-PPC-NEXT: entry:
108113// CHECK-PPC-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
@@ -193,7 +198,7 @@ int v4() { return __builtin_cpu_supports("x86-64-v4"); }
193198// CHECK-PPC-NEXT: [[TMP18:%.*]] = load i32, ptr [[RETVAL]], align 4
194199// CHECK-PPC-NEXT: ret i32 [[TMP18]]
195200//
196- int test (int a ) {
201+ int test_ppc (int a ) {
197202 if (__builtin_cpu_supports ("arch_3_00" )) // HWCAP2
198203 return a ;
199204 else if (__builtin_cpu_supports ("mmu" )) // HWCAP
@@ -211,3 +216,98 @@ int test(int a) {
211216 return a + 5 ;
212217}
213218#endif
219+
220+ #ifdef __riscv
221+ // CHECK-RV32-LABEL: define dso_local i32 @test_riscv(
222+ // CHECK-RV32-SAME: i32 noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] {
223+ // CHECK-RV32-NEXT: entry:
224+ // CHECK-RV32-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
225+ // CHECK-RV32-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
226+ // CHECK-RV32-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
227+ // CHECK-RV32-NEXT: call void @__init_riscv_feature_bits()
228+ // CHECK-RV32-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
229+ // CHECK-RV32-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1
230+ // CHECK-RV32-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1
231+ // CHECK-RV32-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
232+ // CHECK-RV32: if.then:
233+ // CHECK-RV32-NEXT: store i32 3, ptr [[RETVAL]], align 4
234+ // CHECK-RV32-NEXT: br label [[RETURN:%.*]]
235+ // CHECK-RV32: if.else:
236+ // CHECK-RV32-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
237+ // CHECK-RV32-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4
238+ // CHECK-RV32-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4
239+ // CHECK-RV32-NEXT: br i1 [[TMP5]], label [[IF_THEN1:%.*]], label [[IF_ELSE2:%.*]]
240+ // CHECK-RV32: if.then1:
241+ // CHECK-RV32-NEXT: store i32 7, ptr [[RETVAL]], align 4
242+ // CHECK-RV32-NEXT: br label [[RETURN]]
243+ // CHECK-RV32: if.else2:
244+ // CHECK-RV32-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
245+ // CHECK-RV32-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
246+ // CHECK-RV32-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
247+ // CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
248+ // CHECK-RV32: if.then3:
249+ // CHECK-RV32-NEXT: store i32 11, ptr [[RETVAL]], align 4
250+ // CHECK-RV32-NEXT: br label [[RETURN]]
251+ // CHECK-RV32: if.end:
252+ // CHECK-RV32-NEXT: br label [[IF_END4:%.*]]
253+ // CHECK-RV32: if.end4:
254+ // CHECK-RV32-NEXT: br label [[IF_END5:%.*]]
255+ // CHECK-RV32: if.end5:
256+ // CHECK-RV32-NEXT: store i32 0, ptr [[RETVAL]], align 4
257+ // CHECK-RV32-NEXT: br label [[RETURN]]
258+ // CHECK-RV32: return:
259+ // CHECK-RV32-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
260+ // CHECK-RV32-NEXT: ret i32 [[TMP9]]
261+ //
262+ // CHECK-RV64-LABEL: define dso_local signext i32 @test_riscv(
263+ // CHECK-RV64-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
264+ // CHECK-RV64-NEXT: entry:
265+ // CHECK-RV64-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
266+ // CHECK-RV64-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
267+ // CHECK-RV64-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
268+ // CHECK-RV64-NEXT: call void @__init_riscv_feature_bits()
269+ // CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
270+ // CHECK-RV64-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1
271+ // CHECK-RV64-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1
272+ // CHECK-RV64-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
273+ // CHECK-RV64: if.then:
274+ // CHECK-RV64-NEXT: store i32 3, ptr [[RETVAL]], align 4
275+ // CHECK-RV64-NEXT: br label [[RETURN:%.*]]
276+ // CHECK-RV64: if.else:
277+ // CHECK-RV64-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
278+ // CHECK-RV64-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4
279+ // CHECK-RV64-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4
280+ // CHECK-RV64-NEXT: br i1 [[TMP5]], label [[IF_THEN1:%.*]], label [[IF_ELSE2:%.*]]
281+ // CHECK-RV64: if.then1:
282+ // CHECK-RV64-NEXT: store i32 7, ptr [[RETVAL]], align 4
283+ // CHECK-RV64-NEXT: br label [[RETURN]]
284+ // CHECK-RV64: if.else2:
285+ // CHECK-RV64-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
286+ // CHECK-RV64-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
287+ // CHECK-RV64-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
288+ // CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
289+ // CHECK-RV64: if.then3:
290+ // CHECK-RV64-NEXT: store i32 11, ptr [[RETVAL]], align 4
291+ // CHECK-RV64-NEXT: br label [[RETURN]]
292+ // CHECK-RV64: if.end:
293+ // CHECK-RV64-NEXT: br label [[IF_END4:%.*]]
294+ // CHECK-RV64: if.end4:
295+ // CHECK-RV64-NEXT: br label [[IF_END5:%.*]]
296+ // CHECK-RV64: if.end5:
297+ // CHECK-RV64-NEXT: store i32 0, ptr [[RETVAL]], align 4
298+ // CHECK-RV64-NEXT: br label [[RETURN]]
299+ // CHECK-RV64: return:
300+ // CHECK-RV64-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
301+ // CHECK-RV64-NEXT: ret i32 [[TMP9]]
302+ //
303+ int test_riscv (int a ) {
304+ __builtin_cpu_init ();
305+ if (__builtin_cpu_supports ("a" ))
306+ return 3 ;
307+ else if (__builtin_cpu_supports ("c" ))
308+ return 7 ;
309+ else if (__builtin_cpu_supports ("v" ))
310+ return 11 ;
311+ return 0 ;
312+ }
313+ #endif
0 commit comments