Use the DataLayout-aware TargetFolder instead of ConstantFolder in Clang's CGBuilder. The primary impact of this change is that GEP constant expressions are now emitted in canonical `getelementptr i8` form. This is in preparation for the migration to ptradd, which requires this form. Part of the test updates were performed by Claude Code and reviewed by me.
362 lines
17 KiB
C
362 lines
17 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3
|
|
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | \
|
|
// RUN: FileCheck %s --check-prefix=CHECK-X86
|
|
// RUN: %clang_cc1 -triple ppc64le-linux-gnu -emit-llvm -o - %s | FileCheck %s \
|
|
// RUN: --check-prefix=CHECK-PPC
|
|
// RUN: %clang_cc1 -triple riscv32-linux-gnu -emit-llvm -o - %s | FileCheck %s \
|
|
// RUN: --check-prefix=CHECK-RV32
|
|
// RUN: %clang_cc1 -triple riscv64-linux-gnu -emit-llvm -o - %s | FileCheck %s \
|
|
// RUN: --check-prefix=CHECK-RV64
|
|
#ifdef __x86_64__
|
|
|
|
// Test that we have the structure definition, the gep offsets, the name of the
|
|
// global, the bit grab, and the icmp correct.
|
|
extern void a(const char *);
|
|
|
|
|
|
// CHECK-X86-LABEL: define dso_local i32 @main(
|
|
// CHECK-X86-SAME: ) #[[ATTR0:[0-9]+]] {
|
|
// CHECK-X86-NEXT: entry:
|
|
// CHECK-X86-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK-X86-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
|
// CHECK-X86-NEXT: call void @__cpu_indicator_init()
|
|
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12), align 4
|
|
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 256
|
|
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 256
|
|
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
|
|
// CHECK-X86-NEXT: br i1 [[TMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
// CHECK-X86: if.then:
|
|
// CHECK-X86-NEXT: call void @a(ptr noundef @.str)
|
|
// CHECK-X86-NEXT: br label [[IF_END]]
|
|
// CHECK-X86: if.end:
|
|
// CHECK-X86-NEXT: [[TMP4:%.*]] = load i32, ptr @__cpu_features2, align 4
|
|
// CHECK-X86-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
|
|
// CHECK-X86-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 1
|
|
// CHECK-X86-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]]
|
|
// CHECK-X86-NEXT: br i1 [[TMP7]], label [[IF_THEN1:%.*]], label [[IF_END2:%.*]]
|
|
// CHECK-X86: if.then1:
|
|
// CHECK-X86-NEXT: call void @a(ptr noundef @.str.1)
|
|
// CHECK-X86-NEXT: br label [[IF_END2]]
|
|
// CHECK-X86: if.end2:
|
|
// CHECK-X86-NEXT: ret i32 0
|
|
//
|
|
int main(void) {
|
|
__builtin_cpu_init();
|
|
|
|
// CHECK: call void @__cpu_indicator_init
|
|
|
|
if (__builtin_cpu_supports("sse4.2"))
|
|
a("sse4.2");
|
|
|
|
|
|
if (__builtin_cpu_supports("gfni"))
|
|
a("gfni");
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// CHECK-X86-LABEL: define dso_local i32 @baseline(
|
|
// CHECK-X86-SAME: ) #[[ATTR0]] {
|
|
// CHECK-X86-NEXT: entry:
|
|
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4), align 4
|
|
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], -2147483648
|
|
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -2147483648
|
|
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
|
|
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
|
|
// CHECK-X86-NEXT: ret i32 [[CONV]]
|
|
//
|
|
int baseline() { return __builtin_cpu_supports("x86-64"); }
|
|
|
|
// CHECK-X86-LABEL: define dso_local i32 @v2(
|
|
// CHECK-X86-SAME: ) #[[ATTR0]] {
|
|
// CHECK-X86-NEXT: entry:
|
|
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
|
|
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 1
|
|
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
|
|
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
|
|
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
|
|
// CHECK-X86-NEXT: ret i32 [[CONV]]
|
|
//
|
|
int v2() { return __builtin_cpu_supports("x86-64-v2"); }
|
|
|
|
// CHECK-X86-LABEL: define dso_local i32 @v3(
|
|
// CHECK-X86-SAME: ) #[[ATTR0]] {
|
|
// CHECK-X86-NEXT: entry:
|
|
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
|
|
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 2
|
|
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 2
|
|
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
|
|
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
|
|
// CHECK-X86-NEXT: ret i32 [[CONV]]
|
|
//
|
|
int v3() { return __builtin_cpu_supports("x86-64-v3"); }
|
|
|
|
// CHECK-X86-LABEL: define dso_local i32 @v4(
|
|
// CHECK-X86-SAME: ) #[[ATTR0]] {
|
|
// CHECK-X86-NEXT: entry:
|
|
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
|
|
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 4
|
|
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4
|
|
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
|
|
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
|
|
// CHECK-X86-NEXT: ret i32 [[CONV]]
|
|
//
|
|
int v4() { return __builtin_cpu_supports("x86-64-v4"); }
|
|
#endif
|
|
|
|
#ifdef __PPC__
|
|
// CHECK-PPC-LABEL: define dso_local signext i32 @test_ppc(
|
|
// CHECK-PPC-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// CHECK-PPC-NEXT: entry:
|
|
// CHECK-PPC-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK-PPC-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
// CHECK-PPC-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[CPU_SUPPORTS:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 2)
|
|
// CHECK-PPC-NEXT: [[TMP0:%.*]] = and i32 [[CPU_SUPPORTS]], 8388608
|
|
// CHECK-PPC-NEXT: [[TMP1:%.*]] = icmp ne i32 [[TMP0]], 0
|
|
// CHECK-PPC-NEXT: br i1 [[TMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
// CHECK-PPC: if.then:
|
|
// CHECK-PPC-NEXT: [[TMP2:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: store i32 [[TMP2]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN:%.*]]
|
|
// CHECK-PPC: if.else:
|
|
// CHECK-PPC-NEXT: [[CPU_SUPPORTS1:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 1)
|
|
// CHECK-PPC-NEXT: [[TMP3:%.*]] = and i32 [[CPU_SUPPORTS1]], 67108864
|
|
// CHECK-PPC-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
// CHECK-PPC-NEXT: br i1 [[TMP4]], label [[IF_THEN2:%.*]], label [[IF_ELSE3:%.*]]
|
|
// CHECK-PPC: if.then2:
|
|
// CHECK-PPC-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP5]], 5
|
|
// CHECK-PPC-NEXT: store i32 [[SUB]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else3:
|
|
// CHECK-PPC-NEXT: [[CPU_IS:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP6:%.*]] = icmp eq i32 [[CPU_IS]], 39
|
|
// CHECK-PPC-NEXT: br i1 [[TMP6]], label [[IF_THEN4:%.*]], label [[IF_ELSE5:%.*]]
|
|
// CHECK-PPC: if.then4:
|
|
// CHECK-PPC-NEXT: [[TMP7:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[TMP8:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
|
|
// CHECK-PPC-NEXT: store i32 [[ADD]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else5:
|
|
// CHECK-PPC-NEXT: [[CPU_IS6:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP9:%.*]] = icmp eq i32 [[CPU_IS6]], 39
|
|
// CHECK-PPC-NEXT: br i1 [[TMP9]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]]
|
|
// CHECK-PPC: if.then7:
|
|
// CHECK-PPC-NEXT: [[TMP10:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 3
|
|
// CHECK-PPC-NEXT: store i32 [[MUL]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else8:
|
|
// CHECK-PPC-NEXT: [[CPU_IS9:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP11:%.*]] = icmp eq i32 [[CPU_IS9]], 33
|
|
// CHECK-PPC-NEXT: br i1 [[TMP11]], label [[IF_THEN10:%.*]], label [[IF_ELSE12:%.*]]
|
|
// CHECK-PPC: if.then10:
|
|
// CHECK-PPC-NEXT: [[TMP12:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[MUL11:%.*]] = mul nsw i32 [[TMP12]], 4
|
|
// CHECK-PPC-NEXT: store i32 [[MUL11]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else12:
|
|
// CHECK-PPC-NEXT: [[CPU_IS13:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP13:%.*]] = icmp eq i32 [[CPU_IS13]], 45
|
|
// CHECK-PPC-NEXT: br i1 [[TMP13]], label [[IF_THEN14:%.*]], label [[IF_ELSE16:%.*]]
|
|
// CHECK-PPC: if.then14:
|
|
// CHECK-PPC-NEXT: [[TMP14:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[ADD15:%.*]] = add nsw i32 [[TMP14]], 3
|
|
// CHECK-PPC-NEXT: store i32 [[ADD15]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else16:
|
|
// CHECK-PPC-NEXT: [[CPU_IS17:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP15:%.*]] = icmp eq i32 [[CPU_IS17]], 46
|
|
// CHECK-PPC-NEXT: br i1 [[TMP15]], label [[IF_THEN18:%.*]], label [[IF_ELSE20:%.*]]
|
|
// CHECK-PPC: if.then18:
|
|
// CHECK-PPC-NEXT: [[TMP16:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[SUB19:%.*]] = sub nsw i32 [[TMP16]], 3
|
|
// CHECK-PPC-NEXT: store i32 [[SUB19]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else20:
|
|
// CHECK-PPC-NEXT: [[CPU_IS21:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP17:%.*]] = icmp eq i32 [[CPU_IS21]], 47
|
|
// CHECK-PPC-NEXT: br i1 [[TMP17]], label [[IF_THEN22:%.*]], label [[IF_ELSE24:%.*]]
|
|
// CHECK-PPC: if.then22:
|
|
// CHECK-PPC-NEXT: [[TMP18:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP18]], 7
|
|
// CHECK-PPC-NEXT: store i32 [[ADD23]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.else24:
|
|
// CHECK-PPC-NEXT: [[CPU_IS25:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
|
|
// CHECK-PPC-NEXT: [[TMP19:%.*]] = icmp eq i32 [[CPU_IS25]], 48
|
|
// CHECK-PPC-NEXT: br i1 [[TMP19]], label [[IF_THEN26:%.*]], label [[IF_END:%.*]]
|
|
// CHECK-PPC: if.then26:
|
|
// CHECK-PPC-NEXT: [[TMP20:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[SUB27:%.*]] = sub nsw i32 [[TMP20]], 7
|
|
// CHECK-PPC-NEXT: store i32 [[SUB27]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: if.end:
|
|
// CHECK-PPC-NEXT: br label [[IF_END28:%.*]]
|
|
// CHECK-PPC: if.end28:
|
|
// CHECK-PPC-NEXT: br label [[IF_END29:%.*]]
|
|
// CHECK-PPC: if.end29:
|
|
// CHECK-PPC-NEXT: br label [[IF_END30:%.*]]
|
|
// CHECK-PPC: if.end30:
|
|
// CHECK-PPC-NEXT: br label [[IF_END31:%.*]]
|
|
// CHECK-PPC: if.end31:
|
|
// CHECK-PPC-NEXT: br label [[IF_END32:%.*]]
|
|
// CHECK-PPC: if.end32:
|
|
// CHECK-PPC-NEXT: br label [[IF_END33:%.*]]
|
|
// CHECK-PPC: if.end33:
|
|
// CHECK-PPC-NEXT: br label [[IF_END34:%.*]]
|
|
// CHECK-PPC: if.end34:
|
|
// CHECK-PPC-NEXT: br label [[IF_END35:%.*]]
|
|
// CHECK-PPC: if.end35:
|
|
// CHECK-PPC-NEXT: [[TMP21:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
// CHECK-PPC-NEXT: [[ADD36:%.*]] = add nsw i32 [[TMP21]], 5
|
|
// CHECK-PPC-NEXT: store i32 [[ADD36]], ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: br label [[RETURN]]
|
|
// CHECK-PPC: return:
|
|
// CHECK-PPC-NEXT: [[TMP22:%.*]] = load i32, ptr [[RETVAL]], align 4
|
|
// CHECK-PPC-NEXT: ret i32 [[TMP22]]
|
|
//
|
|
int test_ppc(int a) {
|
|
if (__builtin_cpu_supports("arch_3_00")) // HWCAP2
|
|
return a;
|
|
else if (__builtin_cpu_supports("mmu")) // HWCAP
|
|
return a - 5;
|
|
else if (__builtin_cpu_is("power7")) // CPUID
|
|
return a + a;
|
|
else if (__builtin_cpu_is("pwr7")) // CPUID
|
|
return a * 3;
|
|
else if (__builtin_cpu_is("ppc970")) // CPUID
|
|
return a * 4;
|
|
else if (__builtin_cpu_is("power8"))
|
|
return a + 3;
|
|
else if (__builtin_cpu_is("power9"))
|
|
return a - 3;
|
|
else if (__builtin_cpu_is("power10"))
|
|
return a + 7;
|
|
else if (__builtin_cpu_is("power11"))
|
|
return a - 7;
|
|
return a + 5;
|
|
}
|
|
#endif
|
|
|
|
#ifdef __riscv
|
|
// CHECK-RV32-LABEL: define dso_local i32 @test_riscv(
|
|
// CHECK-RV32-SAME: i32 noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// CHECK-RV32-NEXT: entry:
|
|
// CHECK-RV32-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK-RV32-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
// CHECK-RV32-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
// CHECK-RV32-NEXT: call void @__init_riscv_feature_bits(ptr null)
|
|
// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i32 8), align 8
|
|
// CHECK-RV32-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1
|
|
// CHECK-RV32-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1
|
|
// CHECK-RV32-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
// CHECK-RV32: if.then:
|
|
// CHECK-RV32-NEXT: store i32 3, ptr [[RETVAL]], align 4
|
|
// CHECK-RV32-NEXT: br label [[RETURN:%.*]]
|
|
// CHECK-RV32: if.else:
|
|
// CHECK-RV32-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i32 8), align 8
|
|
// CHECK-RV32-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4
|
|
// CHECK-RV32-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4
|
|
// CHECK-RV32-NEXT: br i1 [[TMP5]], label [[IF_THEN1:%.*]], label [[IF_ELSE2:%.*]]
|
|
// CHECK-RV32: if.then1:
|
|
// CHECK-RV32-NEXT: store i32 7, ptr [[RETVAL]], align 4
|
|
// CHECK-RV32-NEXT: br label [[RETURN]]
|
|
// CHECK-RV32: if.else2:
|
|
// CHECK-RV32-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i32 8), align 8
|
|
// CHECK-RV32-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
|
|
// CHECK-RV32-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
|
|
// CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
|
|
// CHECK-RV32: if.then3:
|
|
// CHECK-RV32-NEXT: store i32 11, ptr [[RETVAL]], align 4
|
|
// CHECK-RV32-NEXT: br label [[RETURN]]
|
|
// CHECK-RV32: if.else4:
|
|
// CHECK-RV32-NEXT: [[TMP9:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i32 16), align 8
|
|
// CHECK-RV32-NEXT: [[TMP10:%.*]] = and i64 [[TMP9]], 8
|
|
// CHECK-RV32-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
|
|
// CHECK-RV32-NEXT: br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
|
|
// CHECK-RV32: if.then5:
|
|
// CHECK-RV32-NEXT: store i32 13, ptr [[RETVAL]], align 4
|
|
// CHECK-RV32-NEXT: br label [[RETURN]]
|
|
// CHECK-RV32: if.end:
|
|
// CHECK-RV32-NEXT: br label [[IF_END6:%.*]]
|
|
// CHECK-RV32: if.end6:
|
|
// CHECK-RV32-NEXT: br label [[IF_END7:%.*]]
|
|
// CHECK-RV32: if.end7:
|
|
// CHECK-RV32-NEXT: br label [[IF_END8:%.*]]
|
|
// CHECK-RV32: if.end8:
|
|
// CHECK-RV32-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
|
// CHECK-RV32-NEXT: br label [[RETURN]]
|
|
// CHECK-RV32: return:
|
|
// CHECK-RV32-NEXT: [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
|
|
// CHECK-RV32-NEXT: ret i32 [[TMP12]]
|
|
//
|
|
// CHECK-RV64-LABEL: define dso_local signext i32 @test_riscv(
|
|
// CHECK-RV64-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// CHECK-RV64-NEXT: entry:
|
|
// CHECK-RV64-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK-RV64-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
// CHECK-RV64-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
// CHECK-RV64-NEXT: call void @__init_riscv_feature_bits(ptr null)
|
|
// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i64 8), align 8
|
|
// CHECK-RV64-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1
|
|
// CHECK-RV64-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1
|
|
// CHECK-RV64-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
// CHECK-RV64: if.then:
|
|
// CHECK-RV64-NEXT: store i32 3, ptr [[RETVAL]], align 4
|
|
// CHECK-RV64-NEXT: br label [[RETURN:%.*]]
|
|
// CHECK-RV64: if.else:
|
|
// CHECK-RV64-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i64 8), align 8
|
|
// CHECK-RV64-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 4
|
|
// CHECK-RV64-NEXT: [[TMP5:%.*]] = icmp eq i64 [[TMP4]], 4
|
|
// CHECK-RV64-NEXT: br i1 [[TMP5]], label [[IF_THEN1:%.*]], label [[IF_ELSE2:%.*]]
|
|
// CHECK-RV64: if.then1:
|
|
// CHECK-RV64-NEXT: store i32 7, ptr [[RETVAL]], align 4
|
|
// CHECK-RV64-NEXT: br label [[RETURN]]
|
|
// CHECK-RV64: if.else2:
|
|
// CHECK-RV64-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i64 8), align 8
|
|
// CHECK-RV64-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
|
|
// CHECK-RV64-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
|
|
// CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
|
|
// CHECK-RV64: if.then3:
|
|
// CHECK-RV64-NEXT: store i32 11, ptr [[RETVAL]], align 4
|
|
// CHECK-RV64-NEXT: br label [[RETURN]]
|
|
// CHECK-RV64: if.else4:
|
|
// CHECK-RV64-NEXT: [[TMP9:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @__riscv_feature_bits, i64 16), align 8
|
|
// CHECK-RV64-NEXT: [[TMP10:%.*]] = and i64 [[TMP9]], 8
|
|
// CHECK-RV64-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
|
|
// CHECK-RV64-NEXT: br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
|
|
// CHECK-RV64: if.then5:
|
|
// CHECK-RV64-NEXT: store i32 13, ptr [[RETVAL]], align 4
|
|
// CHECK-RV64-NEXT: br label [[RETURN]]
|
|
// CHECK-RV64: if.end:
|
|
// CHECK-RV64-NEXT: br label [[IF_END6:%.*]]
|
|
// CHECK-RV64: if.end6:
|
|
// CHECK-RV64-NEXT: br label [[IF_END7:%.*]]
|
|
// CHECK-RV64: if.end7:
|
|
// CHECK-RV64-NEXT: br label [[IF_END8:%.*]]
|
|
// CHECK-RV64: if.end8:
|
|
// CHECK-RV64-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
|
// CHECK-RV64-NEXT: br label [[RETURN]]
|
|
// CHECK-RV64: return:
|
|
// CHECK-RV64-NEXT: [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
|
|
// CHECK-RV64-NEXT: ret i32 [[TMP12]]
|
|
//
|
|
int test_riscv(int a) {
|
|
__builtin_cpu_init();
|
|
if (__builtin_cpu_supports("a"))
|
|
return 3;
|
|
else if (__builtin_cpu_supports("c"))
|
|
return 7;
|
|
else if (__builtin_cpu_supports("v"))
|
|
return 11;
|
|
else if (__builtin_cpu_supports("zcb"))
|
|
return 13;
|
|
return 0;
|
|
}
|
|
#endif
|