309 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR3// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM5// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG7 8constexpr extern int cx_var = __builtin_is_constant_evaluated();9 10// CIR: cir.global {{.*}} @cx_var = #cir.int<1> : !s32i11// LLVM: @cx_var = {{.*}} i32 112// OGCG: @cx_var = {{.*}} i32 113 14constexpr extern float cx_var_single = __builtin_huge_valf();15 16// CIR: cir.global {{.*}} @cx_var_single = #cir.fp<0x7F800000> : !cir.float17// LLVM: @cx_var_single = {{.*}} float 0x7FF000000000000018// OGCG: @cx_var_single = {{.*}} float 0x7FF000000000000019 20constexpr extern long double cx_var_ld = __builtin_huge_vall();21 22// CIR: cir.global {{.*}} @cx_var_ld = #cir.fp<0x7FFF8000000000000000> : !cir.long_double<!cir.f80>23// LLVM: @cx_var_ld = {{.*}} x86_fp80 0xK7FFF800000000000000024// OGCG: @cx_var_ld = {{.*}} x86_fp80 0xK7FFF800000000000000025 26int is_constant_evaluated() {27 return __builtin_is_constant_evaluated();28}29 30// CIR: cir.func{{.*}} @_Z21is_constant_evaluatedv() -> !s32i31// CIR: %[[ZERO:.+]] = cir.const #cir.int<0>32 33// LLVM: define {{.*}}i32 @_Z21is_constant_evaluatedv()34// LLVM: %[[MEM:.+]] = alloca i3235// LLVM: store i32 0, ptr %[[MEM]]36// LLVM: %[[RETVAL:.+]] = load i32, ptr %[[MEM]]37// LLVM: ret i32 %[[RETVAL]]38// LLVM: }39 40// OGCG: define {{.*}}i32 @_Z21is_constant_evaluatedv()41// OGCG: ret i32 042// OGCG: }43 44long double constant_fp_builtin_ld() {45 return __builtin_fabsl(-0.1L);46}47 48// CIR: cir.func{{.*}} @_Z22constant_fp_builtin_ldv() -> !cir.long_double<!cir.f80>49// CIR: %[[PONE:.+]] = cir.const #cir.fp<1.000000e-01> : !cir.long_double<!cir.f80>50 51// LLVM: define {{.*}}x86_fp80 @_Z22constant_fp_builtin_ldv()52// LLVM: %[[MEM:.+]] = alloca x86_fp8053// LLVM: store x86_fp80 0xK3FFBCCCCCCCCCCCCCCCD, ptr %[[MEM]]54// LLVM: %[[RETVAL:.+]] = load x86_fp80, ptr %[[MEM]]55// LLVM: ret x86_fp80 %[[RETVAL]]56// LLVM: }57 58// OGCG: define {{.*}}x86_fp80 @_Z22constant_fp_builtin_ldv()59// OGCG: ret x86_fp80 0xK3FFBCCCCCCCCCCCCCCCD60// OGCG: }61 62float constant_fp_builtin_single() {63 return __builtin_fabsf(-0.1f);64}65 66// CIR: cir.func{{.*}} @_Z26constant_fp_builtin_singlev() -> !cir.float67// CIR: %[[PONE:.+]] = cir.const #cir.fp<1.000000e-01> : !cir.float68 69// LLVM: define {{.*}}float @_Z26constant_fp_builtin_singlev()70// LLVM: %[[MEM:.+]] = alloca float71// LLVM: store float 0x3FB99999A0000000, ptr %[[MEM]]72// LLVM: %[[RETVAL:.+]] = load float, ptr %[[MEM]]73// LLVM: ret float %[[RETVAL]]74// LLVM: }75 76// OGCG: define {{.*}}float @_Z26constant_fp_builtin_singlev()77// OGCG: ret float 0x3FB99999A000000078// OGCG: }79 80void library_builtins() {81 __builtin_printf(nullptr);82 __builtin_abort();83}84 85// CIR: cir.func{{.*}} @_Z16library_builtinsv()86// CIR: %[[NULL:.+]] = cir.const #cir.ptr<null> : !cir.ptr<!s8i>87// CIR: cir.call @printf(%[[NULL]]) nothrow : (!cir.ptr<!s8i>) -> !s32i88// CIR: cir.call @abort() nothrow : () -> ()89 90// LLVM: define{{.*}} void @_Z16library_builtinsv()91// LLVM: call i32 (ptr, ...) @printf(ptr null)92// LLVM: call void @abort()93 94// OGCG: define{{.*}} void @_Z16library_builtinsv()95// OGCG: call i32 (ptr, ...) @printf(ptr noundef null)96// OGCG: call void @abort()97 98void assume(bool arg) {99 __builtin_assume(arg);100}101 102// CIR: cir.func{{.*}} @_Z6assumeb103// CIR: cir.assume %{{.+}} : !cir.bool104// CIR: }105 106// LLVM: define {{.*}}void @_Z6assumeb107// LLVM: call void @llvm.assume(i1 %{{.+}})108// LLVM: }109 110// OGCG: define {{.*}}void @_Z6assumeb111// OGCG: call void @llvm.assume(i1 %{{.+}})112// OGCG: }113 114void *assume_aligned(void *ptr) {115 return __builtin_assume_aligned(ptr, 16);116}117 118// CIR: @_Z14assume_alignedPv119// CIR: %{{.+}} = cir.assume_aligned %{{.+}} alignment 16 : !cir.ptr<!void>120// CIR: }121 122// LLVM: @_Z14assume_alignedPv123// LLVM: call void @llvm.assume(i1 true) [ "align"(ptr %{{.+}}, i64 16) ]124// LLVM: }125 126// OGCG: @_Z14assume_alignedPv127// OGCG: call void @llvm.assume(i1 true) [ "align"(ptr %{{.+}}, i64 16) ]128// OGCG: }129 130void *assume_aligned_misalignment(void *ptr, unsigned misalignment) {131 return __builtin_assume_aligned(ptr, 16, misalignment);132}133 134// CIR: @_Z27assume_aligned_misalignmentPvj135// CIR: %{{.+}} = cir.assume_aligned %{{.+}} alignment 16[offset %{{.+}} : !u64i] : !cir.ptr<!void>136// CIR: }137 138// LLVM: @_Z27assume_aligned_misalignmentPvj139// LLVM: call void @llvm.assume(i1 true) [ "align"(ptr %{{.+}}, i64 16, i64 %{{.+}}) ]140// LLVM: }141 142// OGCG: @_Z27assume_aligned_misalignmentPvj143// OGCG: call void @llvm.assume(i1 true) [ "align"(ptr %{{.+}}, i64 16, i64 %{{.+}}) ]144// OGCG: }145 146void assume_separate_storage(void *p1, void *p2) {147 __builtin_assume_separate_storage(p1, p2);148}149 150// CIR: cir.func{{.*}} @_Z23assume_separate_storagePvS_151// CIR: cir.assume_separate_storage %{{.+}}, %{{.+}} : !cir.ptr<!void>152// CIR: }153 154// LLVM: define {{.*}}void @_Z23assume_separate_storagePvS_155// LLVM: call void @llvm.assume(i1 true) [ "separate_storage"(ptr %{{.+}}, ptr %{{.+}}) ]156// LLVM: }157 158// OGCG: define {{.*}}void @_Z23assume_separate_storagePvS_159// OGCG: call void @llvm.assume(i1 true) [ "separate_storage"(ptr %{{.+}}, ptr %{{.+}}) ]160// OGCG: }161 162void expect(int x, int y) {163 __builtin_expect(x, y);164}165 166// CIR-LABEL: cir.func{{.*}} @_Z6expectii167// CIR: %[[X:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i168// CIR-NEXT: %[[X_LONG:.+]] = cir.cast integral %[[X]] : !s32i -> !s64i169// CIR-NEXT: %[[Y:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i170// CIR-NEXT: %[[Y_LONG:.+]] = cir.cast integral %[[Y]] : !s32i -> !s64i171// CIR-NEXT: %{{.+}} = cir.expect(%[[X_LONG]], %[[Y_LONG]]) : !s64i172// CIR: }173 174// LLVM-LABEL: define{{.*}} void @_Z6expectii175// LLVM: %[[X:.+]] = load i32, ptr %{{.+}}, align 4176// LLVM-NEXT: %[[X_LONG:.+]] = sext i32 %[[X]] to i64177// LLVM-NEXT: %[[Y:.+]] = load i32, ptr %{{.+}}, align 4178// LLVM-NEXT: %[[Y_LONG:.+]] = sext i32 %[[Y]] to i64179// LLVM-NEXT: %{{.+}} = call i64 @llvm.expect.i64(i64 %[[X_LONG]], i64 %[[Y_LONG]])180// LLVM: }181 182void expect_prob(int x, int y) {183 __builtin_expect_with_probability(x, y, 0.25);184}185 186// CIR-LABEL: cir.func{{.*}} @_Z11expect_probii187// CIR: %[[X:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i188// CIR-NEXT: %[[X_LONG:.+]] = cir.cast integral %[[X]] : !s32i -> !s64i189// CIR-NEXT: %[[Y:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i190// CIR-NEXT: %[[Y_LONG:.+]] = cir.cast integral %[[Y]] : !s32i -> !s64i191// CIR-NEXT: %{{.+}} = cir.expect(%[[X_LONG]], %[[Y_LONG]], 2.500000e-01) : !s64i192// CIR: }193 194// LLVM: define{{.*}} void @_Z11expect_probii195// LLVM: %[[X:.+]] = load i32, ptr %{{.+}}, align 4196// LLVM-NEXT: %[[X_LONG:.+]] = sext i32 %[[X]] to i64197// LLVM-NEXT: %[[Y:.+]] = load i32, ptr %{{.+}}, align 4198// LLVM-NEXT: %[[Y_LONG:.+]] = sext i32 %[[Y]] to i64199// LLVM-NEXT: %{{.+}} = call i64 @llvm.expect.with.probability.i64(i64 %[[X_LONG]], i64 %[[Y_LONG]], double 2.500000e-01)200// LLVM: }201 202void unreachable() {203 __builtin_unreachable();204}205 206// CIR-LABEL: @_Z11unreachablev207// CIR: cir.unreachable208// CIR: }209 210// LLVM-LABEL: @_Z11unreachablev211// LLVM: unreachable212// LLVM: }213 214// OGCG-LABEL: @_Z11unreachablev215// OGCG: unreachable216// OGCG: }217 218void f1();219void unreachable2() {220 __builtin_unreachable();221 f1();222}223 224// CIR-LABEL: @_Z12unreachable2v225// CIR: cir.unreachable226// CIR-NEXT: ^{{.+}}:227// CIR-NEXT: cir.call @_Z2f1v() : () -> ()228// CIR: }229 230// LLVM-LABEL: @_Z12unreachable2v231// LLVM: unreachable232// LLVM: {{.+}}:233// LLVM-NEXT: call void @_Z2f1v()234// LLVM: }235 236// OGCG-LABEL: @_Z12unreachable2v237// OGCG: unreachable238 239void trap() {240 __builtin_trap();241}242 243// CIR-LABEL: @_Z4trapv244// CIR: cir.trap245// CIR: }246 247// LLVM-LABEL: @_Z4trapv248// LLVM: call void @llvm.trap()249// LLVM: }250 251// OGCG-LABEL: @_Z4trapv252// OGCG: call void @llvm.trap()253// OGCG: }254 255void trap2() {256 __builtin_trap();257 f1();258}259 260// CIR-LABEL: @_Z5trap2v261// CIR: cir.trap262// CIR-NEXT: ^{{.+}}:263// CIR-NEXT: cir.call @_Z2f1v() : () -> ()264// CIR: }265 266// LLVM-LABEL: @_Z5trap2v267// LLVM: call void @llvm.trap()268// LLVM-NEXT: unreachable269// LLVM: {{.+}}:270// LLVM-NEXT: call void @_Z2f1v()271// LLVM: }272 273// OGCG-LABEL: define{{.*}} void @_Z5trap2v274// OGCG: call void @llvm.trap()275// OGCG-NEXT: call void @_Z2f1v()276// OGCG: ret void277// OGCG: }278 279void *test_alloca(unsigned long n) {280 return __builtin_alloca(n);281}282 283// CIR-LABEL: @_Z11test_allocam(284// CIR: %{{.+}} = cir.alloca !u8i, !cir.ptr<!u8i>, %{{.+}} : !u64i, ["bi_alloca"]285 286// LLVM-LABEL: @_Z11test_allocam(287// LLVM: alloca i8, i64 %{{.+}}288 289// OGCG-LABEL: @_Z11test_allocam(290// OGCG: alloca i8, i64 %{{.+}}291 292bool test_multiple_allocas(unsigned long n) {293 void *a = __builtin_alloca(n);294 void *b = __builtin_alloca(n);295 return a != b;296}297 298// CIR-LABEL: @_Z21test_multiple_allocasm(299// CIR: %{{.+}} = cir.alloca !u8i, !cir.ptr<!u8i>, %{{.+}} : !u64i, ["bi_alloca"]300// CIR: %{{.+}} = cir.alloca !u8i, !cir.ptr<!u8i>, %{{.+}} : !u64i, ["bi_alloca"]301 302// LLVM-LABEL: @_Z21test_multiple_allocasm(303// LLVM: alloca i8, i64 %{{.+}}304// LLVM: alloca i8, i64 %{{.+}}305 306// OGCG-LABEL: @_Z21test_multiple_allocasm(307// OGCG: alloca i8, i64 %{{.+}}308// OGCG: alloca i8, i64 %{{.+}}309