// 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 ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), 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 ([3 x i32], ptr @__cpu_features2, i32 0, i32 1), 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 ([3 x i32], ptr @__cpu_features2, i32 0, i32 2), 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 ([3 x i32], ptr @__cpu_features2, i32 0, i32 2), 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 ([3 x i32], ptr @__cpu_features2, i32 0, i32 2), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 1), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), 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 ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 1), 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