| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-intrinsics \ | ||
| // RUN: -fptrauth-calls \ | ||
| // RUN: -fptrauth-returns \ | ||
| // RUN: -fptrauth-auth-traps \ | ||
| // RUN: -fptrauth-vtable-pointer-address-discrimination \ | ||
| // RUN: -fptrauth-vtable-pointer-type-discrimination \ | ||
| // RUN: -fptrauth-init-fini %s | \ | ||
| // RUN: FileCheck %s --check-prefix=ALL | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-intrinsics %s | FileCheck %s --check-prefix=INTRIN | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-calls %s | FileCheck %s --check-prefix=CALL | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-returns %s | FileCheck %s --check-prefix=RET | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-auth-traps %s | FileCheck %s --check-prefix=TRAP | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-calls -fptrauth-vtable-pointer-address-discrimination %s | \ | ||
| // RUN: FileCheck %s --check-prefix=VPTRADDR | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination %s | \ | ||
| // RUN: FileCheck %s --check-prefix=VPTRTYPE | ||
|
|
||
| // RUN: %clang_cc1 -triple aarch64-linux -emit-llvm -o - \ | ||
| // RUN: -fptrauth-calls -fptrauth-init-fini %s | \ | ||
| // RUN: FileCheck %s --check-prefix=INITFINI | ||
|
|
||
| // ALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // ALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 127} | ||
|
|
||
| // INTRIN: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // INTRIN: !{i32 1, !"aarch64-elf-pauthabi-version", i32 1} | ||
|
|
||
| // CALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // CALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 2} | ||
|
|
||
| // RET: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // RET: !{i32 1, !"aarch64-elf-pauthabi-version", i32 4} | ||
|
|
||
| // TRAP: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // TRAP: !{i32 1, !"aarch64-elf-pauthabi-version", i32 8} | ||
|
|
||
| // VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-version", i32 18} | ||
|
|
||
| // VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-version", i32 34} | ||
|
|
||
| // INITFINI: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458} | ||
| // INITFINI: !{i32 1, !"aarch64-elf-pauthabi-version", i32 66} | ||
|
|
||
| void foo() {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| // Test/document all of the dependencies between possible AArch64 FMV extensions. | ||
| // Also test the name mangling. | ||
|
|
||
| // RUN: %clang --target=aarch64-linux-gnu --rtlib=compiler-rt -emit-llvm -S -o - %s | FileCheck %s | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Maes() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("aes"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mbf16() #[[bf16_ebf16:[0-9]+]] { | ||
| __attribute__((target_version("bf16"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mbti() #[[bti:[0-9]+]] { | ||
| __attribute__((target_version("bti"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mcrc() #[[crc:[0-9]+]] { | ||
| __attribute__((target_version("crc"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mdgh() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("dgh"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mdit() #[[dit:[0-9]+]] { | ||
| __attribute__((target_version("dit"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mdotprod() #[[dotprod:[0-9]+]] { | ||
| __attribute__((target_version("dotprod"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mdpb() #[[dpb:[0-9]+]] { | ||
| __attribute__((target_version("dpb"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mdpb2() #[[dpb2:[0-9]+]] { | ||
| __attribute__((target_version("dpb2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mebf16() #[[bf16_ebf16:[0-9]+]] { | ||
| __attribute__((target_version("ebf16"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mf32mm() #[[f32mm:[0-9]+]] { | ||
| __attribute__((target_version("f32mm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mf64mm() #[[f64mm:[0-9]+]] { | ||
| __attribute__((target_version("f64mm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mfcma() #[[fcma:[0-9]+]] { | ||
| __attribute__((target_version("fcma"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mflagm() #[[flagm:[0-9]+]] { | ||
| __attribute__((target_version("flagm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mflagm2() #[[flagm2:[0-9]+]] { | ||
| __attribute__((target_version("flagm2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mfp() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("fp"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mfp16() #[[fp16:[0-9]+]] { | ||
| __attribute__((target_version("fp16"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mfp16fml() #[[fp16fml:[0-9]+]] { | ||
| __attribute__((target_version("fp16fml"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mfrintts() #[[frintts:[0-9]+]] { | ||
| __attribute__((target_version("frintts"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mi8mm() #[[i8mm:[0-9]+]] { | ||
| __attribute__((target_version("i8mm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mjscvt() #[[jscvt:[0-9]+]] { | ||
| __attribute__((target_version("jscvt"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mls64() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("ls64"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mls64_accdata() #[[ls64_accdata:[0-9]+]] { | ||
| __attribute__((target_version("ls64_accdata"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mls64_v() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("ls64_v"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mlse() #[[lse:[0-9]+]] { | ||
| __attribute__((target_version("lse"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mmemtag() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("memtag"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mmemtag2() #[[memtag2:[0-9]+]] { | ||
| __attribute__((target_version("memtag2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mmemtag3() #[[memtag2:[0-9]+]] { | ||
| __attribute__((target_version("memtag3"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mmops() #[[mops:[0-9]+]] { | ||
| __attribute__((target_version("mops"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mpmull() #[[pmull:[0-9]+]] { | ||
| __attribute__((target_version("pmull"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mpredres() #[[predres:[0-9]+]] { | ||
| __attribute__((target_version("predres"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mrcpc() #[[rcpc:[0-9]+]] { | ||
| __attribute__((target_version("rcpc"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mrcpc2() #[[rcpc:[0-9]+]] { | ||
| __attribute__((target_version("rcpc2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mrcpc3() #[[rcpc3:[0-9]+]] { | ||
| __attribute__((target_version("rcpc3"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mrdm() #[[rdm:[0-9]+]] { | ||
| __attribute__((target_version("rdm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mrng() #[[rng:[0-9]+]] { | ||
| __attribute__((target_version("rng"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mrpres() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("rpres"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msb() #[[sb:[0-9]+]] { | ||
| __attribute__((target_version("sb"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msha1() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("sha1"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msha2() #[[sha2:[0-9]+]] { | ||
| __attribute__((target_version("sha2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msha3() #[[sha3:[0-9]+]] { | ||
| __attribute__((target_version("sha3"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msimd() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("simd"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msm4() #[[sm4:[0-9]+]] { | ||
| __attribute__((target_version("sm4"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msme() #[[sme:[0-9]+]] { | ||
| __attribute__((target_version("sme"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msme-f64f64() #[[sme_f64f64:[0-9]+]] { | ||
| __attribute__((target_version("sme-f64f64"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msme-i16i64() #[[sme_i16i64:[0-9]+]] { | ||
| __attribute__((target_version("sme-i16i64"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msme2() #[[sme2:[0-9]+]] { | ||
| __attribute__((target_version("sme2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mssbs() #[[ATTR0:[0-9]+]] { | ||
| __attribute__((target_version("ssbs"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mssbs2() #[[ssbs2:[0-9]+]] { | ||
| __attribute__((target_version("ssbs2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve() #[[sve:[0-9]+]] { | ||
| __attribute__((target_version("sve"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve-bf16() #[[sve_bf16_ebf16:[0-9]+]] { | ||
| __attribute__((target_version("sve-bf16"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve-ebf16() #[[sve_bf16_ebf16:[0-9]+]] { | ||
| __attribute__((target_version("sve-ebf16"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve-i8mm() #[[sve_i8mm:[0-9]+]] { | ||
| __attribute__((target_version("sve-i8mm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve2() #[[sve2:[0-9]+]] { | ||
| __attribute__((target_version("sve2"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve2-aes() #[[sve2_aes_sve2_pmull128:[0-9]+]] { | ||
| __attribute__((target_version("sve2-aes"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve2-bitperm() #[[sve2_bitperm:[0-9]+]] { | ||
| __attribute__((target_version("sve2-bitperm"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve2-pmull128() #[[sve2_aes_sve2_pmull128:[0-9]+]] { | ||
| __attribute__((target_version("sve2-pmull128"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve2-sha3() #[[sve2_sha3:[0-9]+]] { | ||
| __attribute__((target_version("sve2-sha3"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Msve2-sm4() #[[sve2_sm4:[0-9]+]] { | ||
| __attribute__((target_version("sve2-sm4"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK: define dso_local i32 @fmv._Mwfxt() #[[wfxt:[0-9]+]] { | ||
| __attribute__((target_version("wfxt"))) int fmv(void) { return 0; } | ||
|
|
||
| // CHECK-NOT: define dso_local i32 @fmv._M{{.*}} | ||
| __attribute__((target_version("non_existent_extension"))) int fmv(void); | ||
|
|
||
| __attribute__((target_version("default"))) int fmv(void); | ||
|
|
||
| int caller() { | ||
| return fmv(); | ||
| } | ||
|
|
||
| // CHECK: attributes #[[ATTR0:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[bf16_ebf16:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[bti:[0-9]+]] = { {{.*}} "target-features"="+bti,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[crc:[0-9]+]] = { {{.*}} "target-features"="+crc,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[dit:[0-9]+]] = { {{.*}} "target-features"="+dit,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[dotprod:[0-9]+]] = { {{.*}} "target-features"="+dotprod,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[dpb:[0-9]+]] = { {{.*}} "target-features"="+ccpp,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[dpb2:[0-9]+]] = { {{.*}} "target-features"="+ccdp,+ccpp,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[f32mm:[0-9]+]] = { {{.*}} "target-features"="+f32mm,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" | ||
| // CHECK: attributes #[[f64mm:[0-9]+]] = { {{.*}} "target-features"="+f64mm,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" | ||
| // CHECK: attributes #[[fcma:[0-9]+]] = { {{.*}} "target-features"="+complxnum,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[flagm:[0-9]+]] = { {{.*}} "target-features"="+flagm,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[flagm2:[0-9]+]] = { {{.*}} "target-features"="+altnzcv,+flagm,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[fp16:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[fp16fml:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[frintts:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fptoint,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[i8mm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+i8mm,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[jscvt:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+jsconv,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[ls64_accdata:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+ls64,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[lse:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+lse,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[memtag2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+mte,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[mops:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+mops,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[pmull:[0-9]+]] = { {{.*}} "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" | ||
| // CHECK: attributes #[[predres:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+predres,+v8a" | ||
| // CHECK: attributes #[[rcpc:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rcpc,+v8a" | ||
| // CHECK: attributes #[[rcpc3:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rcpc,+rcpc3,+v8a" | ||
| // CHECK: attributes #[[rdm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rdm,+v8a" | ||
| // CHECK: attributes #[[rng:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+rand,+v8a" | ||
| // CHECK: attributes #[[sb:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sb,+v8a" | ||
| // CHECK: attributes #[[sha2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sha2,+v8a" | ||
| // CHECK: attributes #[[sha3:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sha2,+sha3,+v8a" | ||
| // CHECK: attributes #[[sm4:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+sm4,+v8a" | ||
| // CHECK: attributes #[[sme:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+v8a" | ||
| // CHECK: attributes #[[sme_f64f64:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme-f64f64,+v8a" | ||
| // CHECK: attributes #[[sme_i16i64:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme-i16i64,+v8a" | ||
| // CHECK: attributes #[[sme2:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+neon,+outline-atomics,+sme,+sme2,+v8a" | ||
| // CHECK: attributes #[[ssbs2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+ssbs,+v8a" | ||
| // CHECK: attributes #[[sve:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" | ||
| // CHECK: attributes #[[sve_bf16_ebf16:[0-9]+]] = { {{.*}} "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" | ||
| // CHECK: attributes #[[sve_i8mm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+i8mm,+neon,+outline-atomics,+sve,+v8a" | ||
| // CHECK: attributes #[[sve2:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+v8a" | ||
| // CHECK: attributes #[[sve2_aes_sve2_pmull128:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-aes,+v8a" | ||
| // CHECK: attributes #[[sve2_bitperm:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-bitperm,+v8a" | ||
| // CHECK: attributes #[[sve2_sha3:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-sha3,+v8a" | ||
| // CHECK: attributes #[[sve2_sm4:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+sve2-sm4,+v8a" | ||
| // CHECK: attributes #[[wfxt:[0-9]+]] = { {{.*}} "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,+wfxt" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Test which driver flags enable/disable Function Multiversioning on aarch64. | ||
|
|
||
| // FMV is enabled for non-android aarch64 targets: | ||
| // RUN: %clang --target=aarch64 --rtlib=compiler-rt -### -c %s 2>&1 | FileCheck -check-prefix=FMV-ENABLED %s | ||
| // RUN: %clang --target=aarch64-linux-gnu --rtlib=compiler-rt -### -c %s 2>&1 | FileCheck -check-prefix=FMV-ENABLED %s | ||
| // RUN: %clang --target=arm64-apple-ios --rtlib=compiler-rt -### -c %s 2>&1 | FileCheck -check-prefix=FMV-ENABLED %s | ||
| // RUN: %clang --target=arm64-apple-macosx --rtlib=compiler-rt -### -c %s 2>&1 | FileCheck -check-prefix=FMV-ENABLED %s | ||
|
|
||
| // android23 defaults to --rtlib=compiler-rt: | ||
| // RUN: %clang --target=aarch64-linux-android23 -### -c %s 2>&1 | FileCheck -check-prefix=FMV-ENABLED %s | ||
| // RUN: %clang --target=aarch64-linux-android23 --rtlib=compiler-rt -### -c %s 2>&1 | FileCheck -check-prefix=FMV-ENABLED %s | ||
|
|
||
| // FMV is disabled without compiler-rt: | ||
| // RUN: %clang --target=aarch64 -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
| // RUN: %clang --target=aarch64-linux-gnu -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
|
|
||
| // Disabled for older android versions: | ||
| // RUN: %clang --rtlib=compiler-rt --target=aarch64-linux-android -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
| // RUN: %clang --rtlib=compiler-rt --target=aarch64-linux-android22 -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
| // RUN: %clang --rtlib=compiler-rt --target=aarch64-linux-android22 -mno-fmv -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
|
|
||
| // Disabled explicitly: | ||
| // RUN: %clang --rtlib=compiler-rt --target=aarch64 -mno-fmv -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
| // RUN: %clang --rtlib=compiler-rt --target=aarch64-linux-android23 -mno-fmv -### -c %s 2>&1 | FileCheck -check-prefix=FMV-DISABLED %s | ||
|
|
||
| // FMV-ENABLED-NOT: "-target-feature" "-fmv" | ||
| // FMV-DISABLED: "-target-feature" "-fmv" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,25 @@ | ||
| // RUN: %clang -### -c --target=aarch64 %s 2>&1 | FileCheck %s --check-prefix NONE | ||
| // NONE: "-cc1" | ||
| // NONE-NOT: "-fptrauth- | ||
|
|
||
| // RUN: %clang -### -c --target=aarch64 \ | ||
| // RUN: -fno-ptrauth-intrinsics -fptrauth-intrinsics \ | ||
| // RUN: -fno-ptrauth-calls -fptrauth-calls \ | ||
| // RUN: -fno-ptrauth-returns -fptrauth-returns \ | ||
| // RUN: -fno-ptrauth-auth-traps -fptrauth-auth-traps \ | ||
| // RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-address-discrimination \ | ||
| // RUN: -fno-ptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-type-discrimination \ | ||
| // RUN: -fno-ptrauth-init-fini -fptrauth-init-fini \ | ||
| // RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL | ||
| // ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" | ||
|
|
||
| // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \ | ||
| // RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \ | ||
| // RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR | ||
| // ERR: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}' | ||
| // ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}' | ||
| // ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}' | ||
| // ERR-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}' | ||
| // ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}' | ||
| // ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}' | ||
| // ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -fnative-half-type -verify %s | ||
|
|
||
| // expected-warning@+1{{cannot mix packoffset elements with nonpackoffset elements in a cbuffer}} | ||
| cbuffer Mix | ||
| { | ||
| float4 M1 : packoffset(c0); | ||
| float M2; | ||
| float M3 : packoffset(c1.y); | ||
| } | ||
|
|
||
| // expected-warning@+1{{cannot mix packoffset elements with nonpackoffset elements in a cbuffer}} | ||
| cbuffer Mix2 | ||
| { | ||
| float4 M4; | ||
| float M5 : packoffset(c1.y); | ||
| float M6 ; | ||
| } | ||
|
|
||
| // expected-error@+1{{attribute 'packoffset' only applies to shader constant in a constant buffer}} | ||
| float4 g : packoffset(c0); | ||
|
|
||
| cbuffer IllegalOffset | ||
| { | ||
| // expected-error@+1{{invalid resource class specifier 't2' for packoffset, expected 'c'}} | ||
| float4 i1 : packoffset(t2); | ||
| // expected-error@+1{{invalid component 'm' used; expected 'x', 'y', 'z', or 'w'}} | ||
| float i2 : packoffset(c1.m); | ||
| } | ||
|
|
||
| cbuffer Overlap | ||
| { | ||
| float4 o1 : packoffset(c0); | ||
| // expected-error@+1{{packoffset overlap between 'o2', 'o1'}} | ||
| float2 o2 : packoffset(c0.z); | ||
| } | ||
|
|
||
| cbuffer CrossReg | ||
| { | ||
| // expected-error@+1{{packoffset cannot cross register boundary}} | ||
| float4 c1 : packoffset(c0.y); | ||
| // expected-error@+1{{packoffset cannot cross register boundary}} | ||
| float2 c2 : packoffset(c1.w); | ||
| } | ||
|
|
||
| struct ST { | ||
| float s; | ||
| }; | ||
|
|
||
| cbuffer Aggregate | ||
| { | ||
| // expected-error@+1{{packoffset cannot cross register boundary}} | ||
| ST A1 : packoffset(c0.y); | ||
| // expected-error@+1{{packoffset cannot cross register boundary}} | ||
| float A2[2] : packoffset(c1.w); | ||
| } | ||
|
|
||
| cbuffer Double { | ||
| // expected-error@+1{{packoffset at 'y' not match alignment 64 required by 'double'}} | ||
| double d : packoffset(c.y); | ||
| // expected-error@+1{{packoffset cannot cross register boundary}} | ||
| double2 d2 : packoffset(c.z); | ||
| // expected-error@+1{{packoffset cannot cross register boundary}} | ||
| double3 d3 : packoffset(c.z); | ||
| } | ||
|
|
||
| cbuffer ParsingFail { | ||
| // expected-error@+1{{expected identifier}} | ||
| float pf0 : packoffset(); | ||
| // expected-error@+1{{expected identifier}} | ||
| float pf1 : packoffset((c0)); | ||
| // expected-error@+1{{expected ')'}} | ||
| float pf2 : packoffset(c0, x); | ||
| // expected-error@+1{{invalid component 'X' used}} | ||
| float pf3 : packoffset(c.X); | ||
| // expected-error@+1{{expected '(' after ''}} | ||
| float pf4 : packoffset; | ||
| // expected-error@+1{{expected identifier}} | ||
| float pf5 : packoffset(; | ||
| // expected-error@+1{{expected '(' after '}} | ||
| float pf6 : packoffset); | ||
| // expected-error@+1{{expected '(' after '}} | ||
| float pf7 : packoffset c0.x; | ||
|
|
||
| // expected-error@+1{{invalid component 'xy' used}} | ||
| float pf8 : packoffset(c0.xy); | ||
| // expected-error@+1{{invalid component 'rg' used}} | ||
| float pf9 : packoffset(c0.rg); | ||
| // expected-error@+1{{invalid component 'yes' used}} | ||
| float pf10 : packoffset(c0.yes); | ||
| // expected-error@+1{{invalid component 'woo'}} | ||
| float pf11 : packoffset(c0.woo); | ||
| // expected-error@+1{{invalid component 'xr' used}} | ||
| float pf12 : packoffset(c0.xr); | ||
| } | ||
|
|
||
| struct ST2 { | ||
| float a; | ||
| float2 b; | ||
| }; | ||
|
|
||
| cbuffer S { | ||
| float S0 : packoffset(c0.y); | ||
| ST2 S1[2] : packoffset(c1); | ||
| // expected-error@+1{{packoffset overlap between 'S2', 'S1'}} | ||
| half2 S2 : packoffset(c1.w); | ||
| half2 S3 : packoffset(c2.w); | ||
| } | ||
|
|
||
| struct ST23 { | ||
| float s0; | ||
| ST2 s1; | ||
| }; | ||
|
|
||
| cbuffer S2 { | ||
| float S20 : packoffset(c0.y); | ||
| ST2 S21 : packoffset(c1); | ||
| half2 S22 : packoffset(c2.w); | ||
| double S23[2] : packoffset(c3); | ||
| // expected-error@+1{{packoffset overlap between 'S24', 'S23'}} | ||
| float S24 : packoffset(c3.z); | ||
| float S25 : packoffset(c4.z); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // RUN: %clang_cc1 %s -fopenacc -verify | ||
|
|
||
| struct NotConvertible{} NC; | ||
| short getS(); | ||
| int getI(); | ||
|
|
||
| void uses() { | ||
| int arr[5]; | ||
|
|
||
| #pragma acc parallel wait | ||
| while(1); | ||
|
|
||
| #pragma acc serial wait() | ||
| while(1); | ||
|
|
||
| #pragma acc kernels wait(getS(), getI()) | ||
| while(1); | ||
|
|
||
| #pragma acc parallel wait(devnum:getS(): getI()) | ||
| while(1); | ||
|
|
||
| #pragma acc parallel wait(devnum:getS(): queues: getI()) wait(devnum:getI(): queues: getS(), getI(), 5) | ||
| while(1); | ||
|
|
||
| // expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}} | ||
| #pragma acc parallel wait(devnum:NC : 5) | ||
| while(1); | ||
|
|
||
| // expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}} | ||
| #pragma acc parallel wait(devnum:5 : NC) | ||
| while(1); | ||
|
|
||
| // expected-error@+3{{OpenACC clause 'wait' requires expression of integer type ('int[5]' invalid)}} | ||
| // expected-error@+2{{OpenACC clause 'wait' requires expression of integer type ('int[5]' invalid)}} | ||
| // expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}} | ||
| #pragma acc parallel wait(devnum:arr : queues: arr, NC, 5) | ||
| while(1); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| // RUN: %clang_cc1 %s -fopenacc -verify | ||
|
|
||
| struct ExplicitConvertOnly { | ||
| explicit operator int() const; // #EXPL_CONV | ||
| } Explicit; | ||
|
|
||
| struct AmbiguousConvert{ | ||
| operator int(); // #AMBIG_INT | ||
| operator short(); // #AMBIG_SHORT | ||
| operator float(); | ||
| } Ambiguous; | ||
|
|
||
| void Test() { | ||
|
|
||
| // expected-error@+3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}} | ||
| // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} | ||
| // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} | ||
| #pragma acc parallel wait(Ambiguous) | ||
| while (true); | ||
|
|
||
| // expected-error@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} | ||
| // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} | ||
| #pragma acc parallel wait(4, Explicit, 5) | ||
| while (true); | ||
|
|
||
| // expected-error@+3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}} | ||
| // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} | ||
| // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} | ||
| #pragma acc parallel wait(queues: Ambiguous, 5) | ||
| while (true); | ||
|
|
||
| // expected-error@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} | ||
| // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} | ||
| #pragma acc parallel wait(devnum: Explicit: 5) | ||
| while (true); | ||
|
|
||
| // expected-error@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} | ||
| // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} | ||
| #pragma acc parallel wait(devnum: Explicit:queues: 5) | ||
| while (true); | ||
|
|
||
| // expected-error@+1{{use of undeclared identifier 'queues'}} | ||
| #pragma acc parallel wait(devnum: queues: 5) | ||
| while (true); | ||
| } | ||
|
|
||
| struct HasInt { | ||
| using IntTy = int; | ||
| using ShortTy = short; | ||
| static constexpr int value = 1; | ||
| static constexpr AmbiguousConvert ACValue; | ||
| static constexpr ExplicitConvertOnly EXValue; | ||
|
|
||
| operator char(); | ||
| }; | ||
|
|
||
| template<typename T> | ||
| void TestInst() { | ||
|
|
||
| #pragma acc parallel wait(T{}) | ||
| while (true); | ||
|
|
||
| #pragma acc parallel wait(devnum:typename T::ShortTy{}:queues:typename T::IntTy{}) | ||
| while (true); | ||
|
|
||
| // expected-error@+4{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}} | ||
| // expected-note@#INST{{in instantiation of function template specialization}} | ||
| // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} | ||
| // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} | ||
| #pragma acc parallel wait(devnum:T::value :queues:T::ACValue) | ||
| while (true); | ||
|
|
||
| // expected-error@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} | ||
| // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} | ||
| // expected-error@+3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}} | ||
| // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} | ||
| // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} | ||
| #pragma acc parallel wait(devnum:T::EXValue :queues:T::ACValue) | ||
| while (true); | ||
|
|
||
| // expected-error@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} | ||
| // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} | ||
| // expected-error@+3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}} | ||
| // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} | ||
| // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} | ||
| #pragma acc parallel wait(T::EXValue, T::ACValue) | ||
| while (true); | ||
|
|
||
| // expected-error@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} | ||
| // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} | ||
| // expected-error@+3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}} | ||
| // expected-note@#AMBIG_INT{{conversion to integral type 'int'}} | ||
| // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}} | ||
| #pragma acc parallel wait(queues: T::EXValue, T::ACValue) | ||
| while (true); | ||
|
|
||
| // expected-error@+1{{no member named 'Invalid' in 'HasInt'}} | ||
| #pragma acc parallel wait(queues: T::Invalid, T::Invalid2) | ||
| while (true); | ||
| } | ||
|
|
||
| void Inst() { | ||
| TestInst<HasInt>(); // #INST | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ set(CTX_PROFILE_SOURCES | |
| ) | ||
|
|
||
| set(CTX_PROFILE_HEADERS | ||
| CtxInstrContextNode.h | ||
| CtxInstrProfiling.h | ||
| ) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| //===--- CtxInstrContextNode.h - Contextual Profile Node --------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| //============================================================================== | ||
| // | ||
| // NOTE! | ||
| // llvm/lib/ProfileData/CtxInstrContextNode.h and | ||
| // compiler-rt/lib/ctx_profile/CtxInstrContextNode.h | ||
| // must be exact copies of eachother | ||
| // | ||
| // compiler-rt creates these objects as part of the instrumentation runtime for | ||
| // contextual profiling. LLVM only consumes them to convert a contextual tree | ||
| // to a bitstream. | ||
| // | ||
| //============================================================================== | ||
|
|
||
| /// The contextual profile is a directed tree where each node has one parent. A | ||
| /// node (ContextNode) corresponds to a function activation. The root of the | ||
| /// tree is at a function that was marked as entrypoint to the compiler. A node | ||
| /// stores counter values for edges and a vector of subcontexts. These are the | ||
| /// contexts of callees. The index in the subcontext vector corresponds to the | ||
| /// index of the callsite (as was instrumented via llvm.instrprof.callsite). At | ||
| /// that index we find a linked list, potentially empty, of ContextNodes. Direct | ||
| /// calls will have 0 or 1 values in the linked list, but indirect callsites may | ||
| /// have more. | ||
| /// | ||
| /// The ContextNode has a fixed sized header describing it - the GUID of the | ||
| /// function, the size of the counter and callsite vectors. It is also an | ||
| /// (intrusive) linked list for the purposes of the indirect call case above. | ||
| /// | ||
| /// Allocation is expected to happen on an Arena. The allocation lays out inline | ||
| /// the counter and subcontexts vectors. The class offers APIs to correctly | ||
| /// reference the latter. | ||
| /// | ||
| /// The layout is as follows: | ||
| /// | ||
| /// [[declared fields][counters vector][vector of ptrs to subcontexts]] | ||
| /// | ||
| /// See also documentation on the counters and subContexts members below. | ||
| /// | ||
| /// The structure of the ContextNode is known to LLVM, because LLVM needs to: | ||
| /// (1) increment counts, and | ||
| /// (2) form a GEP for the position in the subcontext list of a callsite | ||
| /// This means changes to LLVM contextual profile lowering and changes here | ||
| /// must be coupled. | ||
| /// Note: the header content isn't interesting to LLVM (other than its size) | ||
| /// | ||
| /// Part of contextual collection is the notion of "scratch contexts". These are | ||
| /// buffers that are "large enough" to allow for memory-safe acceses during | ||
| /// counter increments - meaning the counter increment code in LLVM doesn't need | ||
| /// to be concerned with memory safety. Their subcontexts never get populated, | ||
| /// though. The runtime code here produces and recognizes them. | ||
|
|
||
| #ifndef LLVM_PROFILEDATA_CTXINSTRCONTEXTNODE_H | ||
| #define LLVM_PROFILEDATA_CTXINSTRCONTEXTNODE_H | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| namespace llvm { | ||
| namespace ctx_profile { | ||
| using GUID = uint64_t; | ||
|
|
||
| class ContextNode final { | ||
| const GUID Guid; | ||
| ContextNode *const Next; | ||
| const uint32_t NrCounters; | ||
| const uint32_t NrCallsites; | ||
|
|
||
| public: | ||
| ContextNode(GUID Guid, uint32_t NrCounters, uint32_t NrCallsites, | ||
| ContextNode *Next = nullptr) | ||
| : Guid(Guid), Next(Next), NrCounters(NrCounters), | ||
| NrCallsites(NrCallsites) {} | ||
|
|
||
| static inline size_t getAllocSize(uint32_t NrCounters, uint32_t NrCallsites) { | ||
| return sizeof(ContextNode) + sizeof(uint64_t) * NrCounters + | ||
| sizeof(ContextNode *) * NrCallsites; | ||
| } | ||
|
|
||
| // The counters vector starts right after the static header. | ||
| uint64_t *counters() { | ||
| ContextNode *addr_after = &(this[1]); | ||
| return reinterpret_cast<uint64_t *>(addr_after); | ||
| } | ||
|
|
||
| uint32_t counters_size() const { return NrCounters; } | ||
| uint32_t callsites_size() const { return NrCallsites; } | ||
|
|
||
| const uint64_t *counters() const { | ||
| return const_cast<ContextNode *>(this)->counters(); | ||
| } | ||
|
|
||
| // The subcontexts vector starts right after the end of the counters vector. | ||
| ContextNode **subContexts() { | ||
| return reinterpret_cast<ContextNode **>(&(counters()[NrCounters])); | ||
| } | ||
|
|
||
| ContextNode *const *subContexts() const { | ||
| return const_cast<ContextNode *>(this)->subContexts(); | ||
| } | ||
|
|
||
| GUID guid() const { return Guid; } | ||
| ContextNode *next() const { return Next; } | ||
|
|
||
| size_t size() const { return getAllocSize(NrCounters, NrCallsites); } | ||
|
|
||
| uint64_t entrycount() const { return counters()[0]; } | ||
| }; | ||
| } // namespace ctx_profile | ||
| } // namespace llvm | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ; | ||
| ; NOTE: if this test fails, please make sure the two files are identical copies | ||
| ; of eachother. | ||
| ; | ||
| ; RUN: diff %crt_src/lib/ctx_profile/CtxInstrContextNode.h %llvm_src/include/llvm/ProfileData/CtxInstrContextNode.h |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # -*- Python -*- | ||
|
|
||
| import os | ||
| import platform | ||
| import re | ||
|
|
||
| import lit.formats | ||
|
|
||
| # Only run the tests on supported OSs. | ||
| if config.host_os not in ["Linux"]: | ||
| config.unsupported = True | ||
|
|
||
|
|
||
| def get_required_attr(config, attr_name): | ||
| attr_value = getattr(config, attr_name, None) | ||
| if attr_value == None: | ||
| lit_config.fatal( | ||
| "No attribute %r in test configuration! You may need to run " | ||
| "tests from your build directory or add this attribute " | ||
| "to lit.site.cfg.py " % attr_name | ||
| ) | ||
| return attr_value | ||
|
|
||
|
|
||
| # Setup config name. | ||
| config.name = "CtxProfile" + config.name_suffix | ||
|
|
||
| # Setup source root. | ||
| config.test_source_root = os.path.dirname(__file__) | ||
| # Default test suffixes. | ||
| config.suffixes = [".c", ".cpp", ".test"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| @LIT_SITE_CFG_IN_HEADER@ | ||
|
|
||
| # Tool-specific config options. | ||
| config.name_suffix = "@CTX_PROFILE_TEST_CONFIG_SUFFIX@" | ||
| config.target_cflags = "@CTX_PROFILE_TEST_TARGET_CFLAGS@" | ||
| config.clang = "@CTX_PROFILE_TEST_TARGET_CC@" | ||
| config.bits = "@CTX_PROFILE_TEST_BITS@" | ||
| config.target_arch = "@CTX_PROFILE_TEST_TARGET_ARCH@" | ||
|
|
||
| # Load common config for all compiler-rt lit tests. | ||
| lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") | ||
|
|
||
| # Load tool-specific config that would do the real work. | ||
| lit_config.load_config(config, "@CTX_PROFILE_LIT_SOURCE_DIR@/lit.cfg.py") |