aboutsummaryrefslogtreecommitdiff
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/C/C2y/n3525.c30
-rw-r--r--clang/test/CIR/CodeGen/object-size-flex-array.c317
-rw-r--r--clang/test/CIR/CodeGen/object-size.c877
-rw-r--r--clang/test/CIR/CodeGen/object-size.cpp108
-rw-r--r--clang/test/CIR/IR/objsize.cir89
-rw-r--r--clang/test/ClangScanDeps/strip-codegen-args.m6
-rw-r--r--clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl163
-rw-r--r--clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl1
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl36
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic.array.hlsl37
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl77
-rw-r--r--clang/test/Driver/HLSL/wconversion.hlsl7
-rw-r--r--clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1250.bc0
-rw-r--r--clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1251.bc0
-rw-r--r--clang/test/Driver/amdgpu-openmp-sanitize-options.c10
-rw-r--r--clang/test/Driver/hip-sanitize-options.hip5
-rw-r--r--clang/test/Driver/rocm-device-libs.cl12
-rw-r--r--clang/test/Parser/lambda-misplaced-capture-default.cpp9
-rw-r--r--clang/test/ParserHLSL/semantic_parsing.hlsl21
-rw-r--r--clang/test/Profile/Inputs/c-counter-overflows.proftext2
-rw-r--r--clang/test/Profile/Inputs/c-general.profdata.v12bin0 -> 2616 bytes
-rw-r--r--clang/test/Profile/Inputs/c-general.proftext12
-rw-r--r--clang/test/Profile/Inputs/c-unprofiled-blocks.proftext4
-rw-r--r--clang/test/Profile/Inputs/cxx-rangefor.proftext2
-rw-r--r--clang/test/Profile/Inputs/cxx-throws.proftext2
-rw-r--r--clang/test/Profile/Inputs/misexpect-switch-default.proftext2
-rw-r--r--clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext2
-rw-r--r--clang/test/Profile/c-collision.c4
-rw-r--r--clang/test/Profile/c-general.c1
-rw-r--r--clang/test/SemaCXX/attr-mode-tmpl.cpp2
-rw-r--r--clang/test/SemaCXX/cxx23-assume.cpp13
-rw-r--r--clang/test/SemaCXX/cxx2b-warn-shadow.cpp26
-rw-r--r--clang/test/SemaCXX/dependent-switch-case.cpp6
-rw-r--r--clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl2
-rw-r--r--clang/test/SemaHLSL/Semantics/semantics-invalid.hlsl17
-rw-r--r--clang/test/SemaHLSL/Semantics/semantics-valid.hlsl33
-rw-r--r--clang/test/SemaHLSL/Types/AggregateSplatConstantExpr.hlsl89
-rw-r--r--clang/test/SemaHLSL/Types/ElementwiseCastConstantExpr.hlsl90
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype.cpp3
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp2
40 files changed, 2048 insertions, 71 deletions
diff --git a/clang/test/C/C2y/n3525.c b/clang/test/C/C2y/n3525.c
new file mode 100644
index 0000000..428df23
--- /dev/null
+++ b/clang/test/C/C2y/n3525.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
+
+/* WG14 N3525: Yes
+ * static_assert without UB
+ *
+ * Ensures that a static_assert declaration cannot defer to runtime; it must
+ * take an integer constant expression that is resolved at compile time.
+ *
+ * Note: implementations are free to extend what is a valid integer constant
+ * expression, and Clang (and GCC) does so. So this test is validating that
+ * we quietly accept a pasing assertion, loudly reject a failing assertion, and
+ * issue a pedantic diagnostic for the extension case.
+ */
+
+static_assert(1); // Okay
+
+static_assert(0); // expected-error {{static assertion failed}}
+
+extern int a;
+static_assert(1 || a); // expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
+
+static_assert(a); // expected-error {{static assertion expression is not an integral constant expression}}
+static_assert(0 || a); // expected-error {{static assertion expression is not an integral constant expression}}
+
+// Note, there is no CodeGen test for this; we have existing tests for the ICE
+// extension, so the pedantic warning is sufficient to verify we're not
+// emitting code which reads 'a' in '1 || a' because of the folding, and
+// there's no way to generate code for reading 'a' in '0 || a' because of the
+// error.
diff --git a/clang/test/CIR/CodeGen/object-size-flex-array.c b/clang/test/CIR/CodeGen/object-size-flex-array.c
new file mode 100644
index 0000000..74229fd
--- /dev/null
+++ b/clang/test/CIR/CodeGen/object-size-flex-array.c
@@ -0,0 +1,317 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR --check-prefix=CIR-NO-STRICT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -emit-llvm -disable-llvm-passes %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM --check-prefix=LLVM-NO-STRICT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -emit-llvm -disable-llvm-passes %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG --check-prefix=OGCG-NO-STRICT
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=0 -emit-cir %s -o %t-strict-0.cir
+// RUN: FileCheck --input-file=%t-strict-0.cir %s --check-prefix=CIR --check-prefix=CIR-STRICT-0
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=0 -emit-llvm -disable-llvm-passes %s -o %t-cir-strict-0.ll
+// RUN: FileCheck --input-file=%t-cir-strict-0.ll %s --check-prefix=LLVM --check-prefix=LLVM-STRICT-0
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fstrict-flex-arrays=0 -emit-llvm -disable-llvm-passes %s -o %t-strict-0.ll
+// RUN: FileCheck --input-file=%t-strict-0.ll %s --check-prefix=OGCG --check-prefix=OGCG-STRICT-0
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=1 -emit-cir %s -o %t-strict-1.cir
+// RUN: FileCheck --input-file=%t-strict-1.cir %s --check-prefix=CIR --check-prefix=CIR-STRICT-1
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=1 -emit-llvm -disable-llvm-passes %s -o %t-cir-strict-1.ll
+// RUN: FileCheck --input-file=%t-cir-strict-1.ll %s --check-prefix=LLVM --check-prefix=LLVM-STRICT-1
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fstrict-flex-arrays=1 -emit-llvm -disable-llvm-passes %s -o %t-strict-1.ll
+// RUN: FileCheck --input-file=%t-strict-1.ll %s --check-prefix=OGCG --check-prefix=OGCG-STRICT-1
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=2 -emit-cir %s -o %t-strict-2.cir
+// RUN: FileCheck --input-file=%t-strict-2.cir %s --check-prefix=CIR --check-prefix=CIR-STRICT-2
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=2 -emit-llvm -disable-llvm-passes %s -o %t-cir-strict-2.ll
+// RUN: FileCheck --input-file=%t-cir-strict-2.ll %s --check-prefix=LLVM --check-prefix=LLVM-STRICT-2
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fstrict-flex-arrays=2 -emit-llvm -disable-llvm-passes %s -o %t-strict-2.ll
+// RUN: FileCheck --input-file=%t-strict-2.ll %s --check-prefix=OGCG --check-prefix=OGCG-STRICT-2
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=3 -emit-cir %s -o %t-strict-3.cir
+// RUN: FileCheck --input-file=%t-strict-3.cir %s --check-prefix=CIR --check-prefix=CIR-STRICT-3
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -fstrict-flex-arrays=3 -emit-llvm -disable-llvm-passes %s -o %t-cir-strict-3.ll
+// RUN: FileCheck --input-file=%t-cir-strict-3.ll %s --check-prefix=LLVM --check-prefix=LLVM-STRICT-3
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fstrict-flex-arrays=3 -emit-llvm -disable-llvm-passes %s -o %t-strict-3.ll
+// RUN: FileCheck --input-file=%t-strict-3.ll %s --check-prefix=OGCG --check-prefix=OGCG-STRICT-3
+
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+
+typedef struct {
+ float f;
+ double c[];
+} foo_t;
+
+typedef struct {
+ float f;
+ double c[0];
+} foo0_t;
+
+typedef struct {
+ float f;
+ double c[1];
+} foo1_t;
+
+typedef struct {
+ float f;
+ double c[2];
+} foo2_t;
+
+// CIR-LABEL: @bar
+// LLVM-LABEL: @bar(
+// OGCG-LABEL: @bar(
+unsigned bar(foo_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-2: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-3: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-3: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-3: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @bar0
+// LLVM-LABEL: @bar0(
+// OGCG-LABEL: @bar0(
+unsigned bar0(foo0_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-2: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-3: cir.const #cir.int<0>
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-3: store i32 0
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-3: ret i32 0
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @bar1
+// LLVM-LABEL: @bar1(
+// OGCG-LABEL: @bar1(
+unsigned bar1(foo1_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-2: cir.const #cir.int<8>
+ // CIR-STRICT-3: cir.const #cir.int<8>
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-2: store i32 8
+ // LLVM-STRICT-3: store i32 8
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-2: ret i32 8
+ // OGCG-STRICT-3: ret i32 8
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @bar2
+// LLVM-LABEL: @bar2(
+// OGCG-LABEL: @bar2(
+unsigned bar2(foo2_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.const #cir.int<16>
+ // CIR-STRICT-2: cir.const #cir.int<16>
+ // CIR-STRICT-3: cir.const #cir.int<16>
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // LLVM-STRICT-1: store i32 16
+ // LLVM-STRICT-2: store i32 16
+ // LLVM-STRICT-3: store i32 16
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false)
+ // OGCG-STRICT-1: ret i32 16
+ // OGCG-STRICT-2: ret i32 16
+ // OGCG-STRICT-3: ret i32 16
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+#define DYNAMIC_OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+
+// CIR-LABEL: @dyn_bar
+// LLVM-LABEL: @dyn_bar(
+// OGCG-LABEL: @dyn_bar(
+unsigned dyn_bar(foo_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-2: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-3: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-3: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-3: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @dyn_bar0
+// LLVM-LABEL: @dyn_bar0(
+// OGCG-LABEL: @dyn_bar0(
+unsigned dyn_bar0(foo0_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-2: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-3: cir.const #cir.int<0>
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-3: store i32 0
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-2: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-3: ret i32 0
+ return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @dyn_bar1
+// LLVM-LABEL: @dyn_bar1(
+// OGCG-LABEL: @dyn_bar1(
+unsigned dyn_bar1(foo1_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-2: cir.const #cir.int<8>
+ // CIR-STRICT-3: cir.const #cir.int<8>
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-2: store i32 8
+ // LLVM-STRICT-3: store i32 8
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-1: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-2: ret i32 8
+ // OGCG-STRICT-3: ret i32 8
+ return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @dyn_bar2
+// LLVM-LABEL: @dyn_bar2(
+// OGCG-LABEL: @dyn_bar2(
+unsigned dyn_bar2(foo2_t *f) {
+ // CIR-NO-STRICT: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-0: cir.objsize max nullunknown dynamic {{.*}} : !cir.ptr<!void> -> !u64i
+ // CIR-STRICT-1: cir.const #cir.int<16>
+ // CIR-STRICT-2: cir.const #cir.int<16>
+ // CIR-STRICT-3: cir.const #cir.int<16>
+ // LLVM-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // LLVM-STRICT-1: store i32 16
+ // LLVM-STRICT-2: store i32 16
+ // LLVM-STRICT-3: store i32 16
+ // OGCG-NO-STRICT: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-0: llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true)
+ // OGCG-STRICT-1: ret i32 16
+ // OGCG-STRICT-2: ret i32 16
+ // OGCG-STRICT-3: ret i32 16
+ return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// Also checks for non-trailing flex-array like members
+
+typedef struct {
+ double c[0];
+ float f;
+} foofoo0_t;
+
+typedef struct {
+ double c[1];
+ float f;
+} foofoo1_t;
+
+typedef struct {
+ double c[2];
+ float f;
+} foofoo2_t;
+
+// CIR-LABEL: @babar0
+// LLVM-LABEL: @babar0(
+// OGCG-LABEL: @babar0(
+unsigned babar0(foofoo0_t *f) {
+ // CIR-NO-STRICT: cir.const #cir.int<0>
+ // CIR-STRICT-0: cir.const #cir.int<0>
+ // CIR-STRICT-1: cir.const #cir.int<0>
+ // CIR-STRICT-2: cir.const #cir.int<0>
+ // CIR-STRICT-3: cir.const #cir.int<0>
+ // LLVM-NO-STRICT: store i32 0
+ // LLVM-STRICT-0: store i32 0
+ // LLVM-STRICT-1: store i32 0
+ // LLVM-STRICT-2: store i32 0
+ // LLVM-STRICT-3: store i32 0
+ // OGCG-NO-STRICT: ret i32 0
+ // OGCG-STRICT-0: ret i32 0
+ // OGCG-STRICT-1: ret i32 0
+ // OGCG-STRICT-2: ret i32 0
+ // OGCG-STRICT-3: ret i32 0
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @babar1
+// LLVM-LABEL: @babar1(
+// OGCG-LABEL: @babar1(
+unsigned babar1(foofoo1_t *f) {
+ // CIR-NO-STRICT: cir.const #cir.int<8>
+ // CIR-STRICT-0: cir.const #cir.int<8>
+ // CIR-STRICT-1: cir.const #cir.int<8>
+ // CIR-STRICT-2: cir.const #cir.int<8>
+ // CIR-STRICT-3: cir.const #cir.int<8>
+ // LLVM-NO-STRICT: store i32 8
+ // LLVM-STRICT-0: store i32 8
+ // LLVM-STRICT-1: store i32 8
+ // LLVM-STRICT-2: store i32 8
+ // LLVM-STRICT-3: store i32 8
+ // OGCG-NO-STRICT: ret i32 8
+ // OGCG-STRICT-0: ret i32 8
+ // OGCG-STRICT-1: ret i32 8
+ // OGCG-STRICT-2: ret i32 8
+ // OGCG-STRICT-3: ret i32 8
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
+
+// CIR-LABEL: @babar2
+// LLVM-LABEL: @babar2(
+// OGCG-LABEL: @babar2(
+unsigned babar2(foofoo2_t *f) {
+ // CIR-NO-STRICT: cir.const #cir.int<16>
+ // CIR-STRICT-0: cir.const #cir.int<16>
+ // CIR-STRICT-1: cir.const #cir.int<16>
+ // CIR-STRICT-2: cir.const #cir.int<16>
+ // CIR-STRICT-3: cir.const #cir.int<16>
+ // LLVM-NO-STRICT: store i32 16
+ // LLVM-STRICT-0: store i32 16
+ // LLVM-STRICT-1: store i32 16
+ // LLVM-STRICT-2: store i32 16
+ // LLVM-STRICT-3: store i32 16
+ // OGCG-NO-STRICT: ret i32 16
+ // OGCG-STRICT-0: ret i32 16
+ // OGCG-STRICT-1: ret i32 16
+ // OGCG-STRICT-2: ret i32 16
+ // OGCG-STRICT-3: ret i32 16
+ return OBJECT_SIZE_BUILTIN(f->c, 1);
+}
diff --git a/clang/test/CIR/CodeGen/object-size.c b/clang/test/CIR/CodeGen/object-size.c
new file mode 100644
index 0000000..1b10fb8b
--- /dev/null
+++ b/clang/test/CIR/CodeGen/object-size.c
@@ -0,0 +1,877 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+char gbuf[63];
+char *gp;
+int gi, gj;
+
+// CIR-LABEL: @test1
+// LLVM-LABEL: define {{.*}} void @test1
+// OGCG-LABEL: define {{.*}} void @test1
+void test1(void) {
+ // CIR: cir.const #cir.int<59>
+ // LLVM: store i32 59
+ // OGCG: store i32 59
+ gi = __builtin_object_size(&gbuf[4], 1);
+}
+
+// CIR-LABEL: @test2
+// LLVM-LABEL: define {{.*}} void @test2
+// OGCG-LABEL: define {{.*}} void @test2
+void test2(void) {
+ // CIR: cir.const #cir.int<63>
+ // LLVM: store i32 63
+ // OGCG: store i32 63
+ gi = __builtin_object_size(gbuf, 1);
+}
+
+// CIR-LABEL: @test3
+// LLVM-LABEL: define {{.*}} void @test3
+// OGCG-LABEL: define {{.*}} void @test3
+void test3(void) {
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&gbuf[100], 1);
+}
+
+// CIR-LABEL: @test4
+// LLVM-LABEL: define {{.*}} void @test4
+// OGCG-LABEL: define {{.*}} void @test4
+void test4(void) {
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)(void*)&gbuf[-1], 1);
+}
+
+// CIR-LABEL: @test5
+// LLVM-LABEL: define {{.*}} void @test5
+// OGCG-LABEL: define {{.*}} void @test5
+void test5(void) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(gp, 0);
+}
+
+// CIR-LABEL: @test6
+// LLVM-LABEL: define {{.*}} void @test6
+// OGCG-LABEL: define {{.*}} void @test6
+void test6(void) {
+ char buf[57];
+
+ // CIR: cir.const #cir.int<53>
+ // LLVM: store i32 53
+ // OGCG: store i32 53
+ gi = __builtin_object_size(&buf[4], 1);
+}
+
+// CIR-LABEL: @test18
+// LLVM-LABEL: define {{.*}} i32 @test18
+// OGCG-LABEL: define {{.*}} i32 @test18
+unsigned test18(int cond) {
+ int a[4], b[4];
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64
+ // OGCG: call i64 @llvm.objectsize.i64
+ return __builtin_object_size(cond ? a : b, 0);
+}
+
+// CIR-LABEL: @test19
+// LLVM-LABEL: define {{.*}} void @test19
+// OGCG-LABEL: define {{.*}} void @test19
+void test19(void) {
+ struct {
+ int a, b;
+ } foo;
+
+ // CIR: cir.const #cir.int<8>
+ // LLVM: store i32 8
+ // OGCG: store i32 8
+ gi = __builtin_object_size(&foo.a, 0);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&foo.a, 1);
+
+ // CIR: cir.const #cir.int<8>
+ // LLVM: store i32 8
+ // OGCG: store i32 8
+ gi = __builtin_object_size(&foo.a, 2);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&foo.a, 3);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&foo.b, 0);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&foo.b, 1);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&foo.b, 2);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&foo.b, 3);
+}
+
+// CIR-LABEL: @test20
+// LLVM-LABEL: define {{.*}} void @test20
+// OGCG-LABEL: define {{.*}} void @test20
+void test20(void) {
+ struct { int t[10]; } t[10];
+
+ // CIR: cir.const #cir.int<380>
+ // LLVM: store i32 380
+ // OGCG: store i32 380
+ gi = __builtin_object_size(&t[0].t[5], 0);
+
+ // CIR: cir.const #cir.int<20>
+ // LLVM: store i32 20
+ // OGCG: store i32 20
+ gi = __builtin_object_size(&t[0].t[5], 1);
+
+ // CIR: cir.const #cir.int<380>
+ // LLVM: store i32 380
+ // OGCG: store i32 380
+ gi = __builtin_object_size(&t[0].t[5], 2);
+
+ // CIR: cir.const #cir.int<20>
+ // LLVM: store i32 20
+ // OGCG: store i32 20
+ gi = __builtin_object_size(&t[0].t[5], 3);
+}
+
+// CIR-LABEL: @test21
+// LLVM-LABEL: define {{.*}} void @test21
+// OGCG-LABEL: define {{.*}} void @test21
+void test21(void) {
+ struct { int t; } t;
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t + 1, 0);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t + 1, 1);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t + 1, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t + 1, 3);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t.t + 1, 0);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t.t + 1, 1);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t.t + 1, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t.t + 1, 3);
+}
+
+// CIR-LABEL: @test22
+// LLVM-LABEL: define {{.*}} void @test22
+// OGCG-LABEL: define {{.*}} void @test22
+void test22(void) {
+ struct { int t[10]; } t[10];
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[10], 0);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[10], 1);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[10], 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[10], 3);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[9].t[10], 0);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[9].t[10], 1);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[9].t[10], 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[9].t[10], 3);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[0] + sizeof(t), 0);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[0] + sizeof(t), 1);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[0] + sizeof(t), 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[0] + sizeof(t), 3);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
+}
+
+struct Test23Ty { int a; int t[10]; };
+
+// CIR-LABEL: @test23
+// LLVM-LABEL: define {{.*}} void @test23
+// OGCG-LABEL: define {{.*}} void @test23
+void test23(struct Test23Ty *p) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(p, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(p, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(p, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(p, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(&p->a, 0);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&p->a, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(&p->a, 2);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&p->a, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(&p->t[5], 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(&p->t[5], 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(&p->t[5], 2);
+
+ // CIR: cir.const #cir.int<20>
+ // LLVM: store i32 20
+ // OGCG: store i32 20
+ gi = __builtin_object_size(&p->t[5], 3);
+}
+
+// CIR-LABEL: @test24
+// LLVM-LABEL: define {{.*}} void @test24
+// OGCG-LABEL: define {{.*}} void @test24
+void test24(void) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size((void*)0, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size((void*)0, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size((void*)0, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((void*)0, 3);
+}
+
+// CIR-LABEL: @test25
+// LLVM-LABEL: define {{.*}} void @test25
+// OGCG-LABEL: define {{.*}} void @test25
+void test25(void) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size((void*)0x1000, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size((void*)0x1000, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size((void*)0x1000, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size((void*)0x1000, 3);
+
+ // Skipping (void*)0 + 0x1000 tests - void pointer arithmetic NYI in CIR
+}
+
+// CIR-LABEL: @test26
+// LLVM-LABEL: define {{.*}} void @test26
+// OGCG-LABEL: define {{.*}} void @test26
+void test26(void) {
+ struct { int v[10]; } t[10];
+
+ // CIR: cir.const #cir.int<316>
+ // LLVM: store i32 316
+ // OGCG: store i32 316
+ gi = __builtin_object_size(&t[1].v[11], 0);
+
+ // CIR: cir.const #cir.int<312>
+ // LLVM: store i32 312
+ // OGCG: store i32 312
+ gi = __builtin_object_size(&t[1].v[12], 1);
+
+ // CIR: cir.const #cir.int<308>
+ // LLVM: store i32 308
+ // OGCG: store i32 308
+ gi = __builtin_object_size(&t[1].v[13], 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&t[1].v[14], 3);
+}
+
+struct Test27IncompleteTy;
+
+// CIR-LABEL: @test27
+// LLVM-LABEL: define {{.*}} void @test27
+// OGCG-LABEL: define {{.*}} void @test27
+void test27(struct Test27IncompleteTy *t) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(t, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(t, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(t, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(t, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(&test27, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(&test27, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(&test27, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(&test27, 3);
+}
+
+// CIR-LABEL: @test28
+// LLVM-LABEL: define {{.*}} void @test28
+// OGCG-LABEL: define {{.*}} void @test28
+void test28(void) {
+ struct { int v[10]; } t[10];
+
+ // CIR: cir.const #cir.int<360>
+ // LLVM: store i32 360
+ // OGCG: store i32 360
+ gi = __builtin_object_size((char*)((short*)(&t[1])), 0);
+
+ // CIR: cir.const #cir.int<360>
+ // LLVM: store i32 360
+ // OGCG: store i32 360
+ gi = __builtin_object_size((char*)((short*)(&t[1])), 1);
+
+ // CIR: cir.const #cir.int<360>
+ // LLVM: store i32 360
+ // OGCG: store i32 360
+ gi = __builtin_object_size((char*)((short*)(&t[1])), 2);
+
+ // CIR: cir.const #cir.int<360>
+ // LLVM: store i32 360
+ // OGCG: store i32 360
+ gi = __builtin_object_size((char*)((short*)(&t[1])), 3);
+
+ // CIR: cir.const #cir.int<356>
+ // LLVM: store i32 356
+ // OGCG: store i32 356
+ gi = __builtin_object_size((char*)((short*)(&t[1].v[1])), 0);
+
+ // CIR: cir.const #cir.int<36>
+ // LLVM: store i32 36
+ // OGCG: store i32 36
+ gi = __builtin_object_size((char*)((short*)(&t[1].v[1])), 1);
+
+ // CIR: cir.const #cir.int<356>
+ // LLVM: store i32 356
+ // OGCG: store i32 356
+ gi = __builtin_object_size((char*)((short*)(&t[1].v[1])), 2);
+
+ // CIR: cir.const #cir.int<36>
+ // LLVM: store i32 36
+ // OGCG: store i32 36
+ gi = __builtin_object_size((char*)((short*)(&t[1].v[1])), 3);
+}
+
+struct DynStructVar {
+ char fst[16];
+ char snd[];
+};
+
+struct DynStruct0 {
+ char fst[16];
+ char snd[0];
+};
+
+struct DynStruct1 {
+ char fst[16];
+ char snd[1];
+};
+
+struct StaticStruct {
+ char fst[16];
+ char snd[2];
+};
+
+// CIR-LABEL: @test29
+// LLVM-LABEL: define {{.*}} void @test29
+// OGCG-LABEL: define {{.*}} void @test29
+void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
+ struct DynStruct1 *d1, struct StaticStruct *ss) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(dv->snd, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(dv->snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(dv->snd, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(dv->snd, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(d0->snd, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(d0->snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(d0->snd, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(d0->snd, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(d1->snd, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(d1->snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(d1->snd, 2);
+
+ // CIR: cir.const #cir.int<1>
+ // LLVM: store i32 1
+ // OGCG: store i32 1
+ gi = __builtin_object_size(d1->snd, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(ss->snd, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(ss->snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(ss->snd, 2);
+
+ // CIR: cir.const #cir.int<2>
+ // LLVM: store i32 2
+ // OGCG: store i32 2
+ gi = __builtin_object_size(ss->snd, 3);
+}
+
+// CIR-LABEL: @test30
+// LLVM-LABEL: define {{.*}} void @test30
+// OGCG-LABEL: define {{.*}} void @test30
+void test30(void) {
+ struct { struct DynStruct1 fst, snd; } *nested;
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(nested->fst.snd, 0);
+
+ // CIR: cir.const #cir.int<1>
+ // LLVM: store i32 1
+ // OGCG: store i32 1
+ gi = __builtin_object_size(nested->fst.snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(nested->fst.snd, 2);
+
+ // CIR: cir.const #cir.int<1>
+ // LLVM: store i32 1
+ // OGCG: store i32 1
+ gi = __builtin_object_size(nested->fst.snd, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(nested->snd.snd, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(nested->snd.snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(nested->snd.snd, 2);
+
+ // CIR: cir.const #cir.int<1>
+ // LLVM: store i32 1
+ // OGCG: store i32 1
+ gi = __builtin_object_size(nested->snd.snd, 3);
+
+ union { struct DynStruct1 d1; char c[1]; } *u;
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(u->c, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(u->c, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(u->c, 2);
+
+ // CIR: cir.const #cir.int<1>
+ // LLVM: store i32 1
+ // OGCG: store i32 1
+ gi = __builtin_object_size(u->c, 3);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(u->d1.snd, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(u->d1.snd, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(u->d1.snd, 2);
+
+ // CIR: cir.const #cir.int<1>
+ // LLVM: store i32 1
+ // OGCG: store i32 1
+ gi = __builtin_object_size(u->d1.snd, 3);
+}
+
+// CIR-LABEL: @test32
+// LLVM-LABEL: define {{.*}} i64 @test32
+// OGCG-LABEL: define {{.*}} i64 @test32
+static struct DynStructVar D32 = {
+ .fst = {},
+ .snd = { 0, 1, 2, },
+};
+unsigned long test32(void) {
+ // CIR: cir.const #cir.int<19>
+ // LLVM: store i64 19
+ // OGCG: ret i64 19
+ return __builtin_object_size(&D32, 1);
+}
+
+// CIR-LABEL: @test33
+// LLVM-LABEL: define {{.*}} i64 @test33
+// OGCG-LABEL: define {{.*}} i64 @test33
+static struct DynStructVar D33 = {
+ .fst = {},
+ .snd = {},
+};
+unsigned long test33(void) {
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i64 16
+ // OGCG: ret i64 16
+ return __builtin_object_size(&D33, 1);
+}
+
+// CIR-LABEL: @test34
+// LLVM-LABEL: define {{.*}} i64 @test34
+// OGCG-LABEL: define {{.*}} i64 @test34
+static struct DynStructVar D34 = {
+ .fst = {},
+};
+unsigned long test34(void) {
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i64 16
+ // OGCG: ret i64 16
+ return __builtin_object_size(&D34, 1);
+}
+
+// CIR-LABEL: @test35
+// LLVM-LABEL: define {{.*}} i64 @test35
+// OGCG-LABEL: define {{.*}} i64 @test35
+unsigned long test35(void) {
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i64 16
+ // OGCG: ret i64 16
+ return __builtin_object_size(&(struct DynStructVar){}, 1);
+}
+
+// CIR-LABEL: @test37
+// LLVM-LABEL: define {{.*}} i64 @test37
+// OGCG-LABEL: define {{.*}} i64 @test37
+struct Z { struct A { int x, y[]; } z; int a; int b[]; };
+static struct Z my_z = { .b = {1,2,3} };
+unsigned long test37(void) {
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i64 4
+ // OGCG: ret i64 4
+ return __builtin_object_size(&my_z.z, 1);
+}
+
+// CIR-LABEL: @PR30346
+// LLVM-LABEL: define {{.*}} void @PR30346
+// OGCG-LABEL: define {{.*}} void @PR30346
+void PR30346(void) {
+ struct sa_family_t {};
+ struct sockaddr {
+ struct sa_family_t sa_family;
+ char sa_data[14];
+ };
+
+ struct sockaddr *sa;
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(sa->sa_data, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
+ gi = __builtin_object_size(sa->sa_data, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
+ gi = __builtin_object_size(sa->sa_data, 2);
+
+ // CIR: cir.const #cir.int<14>
+ // LLVM: store i32 14
+ // OGCG: store i32 14
+ gi = __builtin_object_size(sa->sa_data, 3);
+}
+
+extern char incomplete_char_array[];
+
+// CIR-LABEL: @incomplete_and_function_types
+// LLVM-LABEL: define {{.*}} void @incomplete_and_function_types
+// OGCG-LABEL: define {{.*}} void @incomplete_and_function_types
+void incomplete_and_function_types(void) {
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0
+ // OGCG: call i64 @llvm.objectsize.i64.p0
+ gi = __builtin_object_size(incomplete_char_array, 0);
+
+ // CIR: cir.objsize max nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0
+ // OGCG: call i64 @llvm.objectsize.i64.p0
+ gi = __builtin_object_size(incomplete_char_array, 1);
+
+ // CIR: cir.objsize min nullunknown {{.*}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0
+ // OGCG: call i64 @llvm.objectsize.i64.p0
+ gi = __builtin_object_size(incomplete_char_array, 2);
+
+ // CIR: cir.const #cir.int<0>
+ // LLVM: store i32 0
+ // OGCG: store i32 0
+ gi = __builtin_object_size(incomplete_char_array, 3);
+}
+
+// CIR-LABEL: @deeply_nested
+// LLVM-LABEL: define {{.*}} void @deeply_nested
+// OGCG-LABEL: define {{.*}} void @deeply_nested
+void deeply_nested(void) {
+ struct {
+ struct {
+ struct {
+ struct {
+ int e[2];
+ char f;
+ } d[2];
+ } c[2];
+ } b[2];
+ } *a;
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 1);
+
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 3);
+}
diff --git a/clang/test/CIR/CodeGen/object-size.cpp b/clang/test/CIR/CodeGen/object-size.cpp
new file mode 100644
index 0000000..b60e245
--- /dev/null
+++ b/clang/test/CIR/CodeGen/object-size.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+// C++-specific tests for __builtin_object_size
+
+int gi;
+
+// CIR-LABEL: @_Z5test1v
+// LLVM-LABEL: define{{.*}} void @_Z5test1v()
+// OGCG-LABEL: define{{.*}} void @_Z5test1v()
+void test1() {
+ // Guaranteeing that our cast removal logic doesn't break more interesting
+ // cases.
+ struct A { int a; };
+ struct B { int b; };
+ struct C: public A, public B {};
+
+ C c;
+
+ // CIR: cir.const #cir.int<8>
+ // LLVM: store i32 8
+ // OGCG: store i32 8
+ gi = __builtin_object_size(&c, 0);
+ // CIR: cir.const #cir.int<8>
+ // LLVM: store i32 8
+ // OGCG: store i32 8
+ gi = __builtin_object_size((A*)&c, 0);
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size((B*)&c, 0);
+
+ // CIR: cir.const #cir.int<8>
+ // LLVM: store i32 8
+ // OGCG: store i32 8
+ gi = __builtin_object_size((char*)&c, 0);
+ // CIR: cir.const #cir.int<8>
+ // LLVM: store i32 8
+ // OGCG: store i32 8
+ gi = __builtin_object_size((char*)(A*)&c, 0);
+ // CIR: cir.const #cir.int<4>
+ // LLVM: store i32 4
+ // OGCG: store i32 4
+ gi = __builtin_object_size((char*)(B*)&c, 0);
+}
+
+// CIR-LABEL: @_Z5test2v()
+// LLVM-LABEL: define{{.*}} void @_Z5test2v()
+// OGCG-LABEL: define{{.*}} void @_Z5test2v()
+void test2() {
+ struct A { char buf[16]; };
+ struct B : A {};
+ struct C { int i; B bs[1]; } *c;
+
+ // CIR: cir.objsize max nullunknown %{{.+}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false)
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false)
+ gi = __builtin_object_size(&c->bs[0], 0);
+ // CIR: cir.objsize max nullunknown %{{.+}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false)
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false)
+ gi = __builtin_object_size(&c->bs[0], 1);
+ // CIR: cir.objsize min nullunknown %{{.+}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false)
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false)
+ gi = __builtin_object_size(&c->bs[0], 2);
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i32 16
+ // OGCG: store i32 16
+ gi = __builtin_object_size(&c->bs[0], 3);
+
+ // NYI: DerivedToBase cast
+ // gi = __builtin_object_size((A*)&c->bs[0], 0);
+
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i32 16
+ // OGCG: store i32 16
+ gi = __builtin_object_size((A*)&c->bs[0], 1);
+
+ // NYI: DerivedToBase cast
+ // gi = __builtin_object_size((A*)&c->bs[0], 2);
+
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i32 16
+ // OGCG: store i32 16
+ gi = __builtin_object_size((A*)&c->bs[0], 3);
+
+ // CIR: cir.objsize max nullunknown %{{.+}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false)
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false)
+ gi = __builtin_object_size(&c->bs[0].buf[0], 0);
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i32 16
+ // OGCG: store i32 16
+ gi = __builtin_object_size(&c->bs[0].buf[0], 1);
+ // CIR: cir.objsize min nullunknown %{{.+}} : !cir.ptr<!void> -> !u64i
+ // LLVM: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false)
+ // OGCG: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false)
+ gi = __builtin_object_size(&c->bs[0].buf[0], 2);
+ // CIR: cir.const #cir.int<16>
+ // LLVM: store i32 16
+ // OGCG: store i32 16
+ gi = __builtin_object_size(&c->bs[0].buf[0], 3);
+}
diff --git a/clang/test/CIR/IR/objsize.cir b/clang/test/CIR/IR/objsize.cir
new file mode 100644
index 0000000..bc24551
--- /dev/null
+++ b/clang/test/CIR/IR/objsize.cir
@@ -0,0 +1,89 @@
+// Test the cir.objsize operation can parse and print correctly (roundtrip)
+// with all possible combinations of optional attributes
+
+// RUN: cir-opt %s --verify-roundtrip | FileCheck %s
+
+!u64i = !cir.int<u, 64>
+!void = !cir.void
+
+module {
+ cir.func @test_max(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize max %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_max_nullunknown(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize max nullunknown %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_max_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize max dynamic %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_max_nullunknown_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize max nullunknown dynamic %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_min(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize min %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_min_nullunknown(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize min nullunknown %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_min_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize min dynamic %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+
+ cir.func @test_min_nullunknown_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+ %0 = cir.objsize min nullunknown dynamic %arg0 : !cir.ptr<!void> -> !u64i
+ cir.return %0 : !u64i
+ }
+}
+
+// CHECK: cir.func @test_max(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize max %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_max_nullunknown(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize max nullunknown %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_max_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize max dynamic %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_max_nullunknown_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize max nullunknown dynamic %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_min(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize min %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_min_nullunknown(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize min nullunknown %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_min_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize min dynamic %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
+
+// CHECK: cir.func @test_min_nullunknown_dynamic(%arg0: !cir.ptr<!void>) -> !u64i {
+// CHECK: %0 = cir.objsize min nullunknown dynamic %arg0 : !cir.ptr<!void> -> !u64i
+// CHECK: cir.return %0 : !u64i
+// CHECK: }
diff --git a/clang/test/ClangScanDeps/strip-codegen-args.m b/clang/test/ClangScanDeps/strip-codegen-args.m
index 71171f4..f2cec62 100644
--- a/clang/test/ClangScanDeps/strip-codegen-args.m
+++ b/clang/test/ClangScanDeps/strip-codegen-args.m
@@ -16,6 +16,7 @@
// CHECK-NOT: "-flto"
// CHECK-NOT: "-fno-autolink"
// CHECK-NOT: "-mrelax-relocations=no"
+// CHECK-NOT: "-mspeculative-load-hardening"
// CHECK: ]
// CHECK: "name": "A"
// CHECK: }
@@ -39,6 +40,11 @@
"command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -O2 -flto=full -fsyntax-only DIR/t3.m",
"file": "DIR/t2.m"
}
+ {
+ "directory": "DIR",
+ "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -O2 -mspeculative-load-hardening -fsyntax-only DIR/t3.m",
+ "file": "DIR/t3.m"
+ }
]
//--- modules/A/module.modulemap
diff --git a/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl b/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
index 368d652..51b0f81 100644
--- a/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl
@@ -1,161 +1,260 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \
-// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -DTARGET=dx
+// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN: -fnative-int16-type -emit-llvm -O1 -o - | FileCheck %s -DTARGET=dx \
+// RUN: --check-prefixes=CHECK,DXCHECK
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \
-// RUN: -emit-llvm -disable-llvm-passes \
-// RUN: -o - | FileCheck %s -DTARGET=spv
+// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
+// RUN: -fnative-int16-type -emit-llvm -O1 -o - | FileCheck %s -DTARGET=spv
#ifdef __HLSL_ENABLE_16_BIT
// CHECK-LABEL: test_firstbithigh_ushort
-// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbituhigh.i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 15, [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1
+// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]]
+// CHECK-NEXT: ret i32
uint test_firstbithigh_ushort(uint16_t p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ushort2
-// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 15), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]]
+// CHECK-NEXT: ret <2 x i32>
uint2 test_firstbithigh_ushort2(uint16_t2 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ushort3
-// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 15), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]]
+// CHECK-NEXT: ret <3 x i32>
uint3 test_firstbithigh_ushort3(uint16_t3 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ushort4
-// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 15), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: ret <4 x i32>
uint4 test_firstbithigh_ushort4(uint16_t4 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_short
-// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbitshigh.i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 15, [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1
+// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]]
+// CHECK-NEXT: ret i32
uint test_firstbithigh_short(int16_t p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_short2
-// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 15), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]]
+// CHECK-NEXT: ret <2 x i32>
uint2 test_firstbithigh_short2(int16_t2 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_short3
-// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 15), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]]
+// CHECK-NEXT: ret <3 x i32>
uint3 test_firstbithigh_short3(int16_t3 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_short4
-// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 15), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: ret <4 x i32>
uint4 test_firstbithigh_short4(int16_t4 p0) {
return firstbithigh(p0);
}
#endif // __HLSL_ENABLE_16_BIT
// CHECK-LABEL: test_firstbithigh_uint
-// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbituhigh.i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1
+// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]]
+// CHECK-NEXT: ret i32
uint test_firstbithigh_uint(uint p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_uint2
-// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]]
+// CHECK-NEXT: ret <2 x i32>
uint2 test_firstbithigh_uint2(uint2 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_uint3
-// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]]
+// CHECK-NEXT: ret <3 x i32>
uint3 test_firstbithigh_uint3(uint3 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_uint4
-// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: ret <4 x i32>
uint4 test_firstbithigh_uint4(uint4 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ulong
-// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbituhigh.i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 63, [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1
+// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]]
+// CHECK-NEXT: ret i32
uint test_firstbithigh_ulong(uint64_t p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ulong2
-// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 63), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]]
+// CHECK-NEXT: ret <2 x i32>
uint2 test_firstbithigh_ulong2(uint64_t2 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ulong3
-// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 63), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]]
+// CHECK-NEXT: ret <3 x i32>
uint3 test_firstbithigh_ulong3(uint64_t3 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_ulong4
-// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 63), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: ret <4 x i32>
uint4 test_firstbithigh_ulong4(uint64_t4 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_int
-// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbitshigh.i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1
+// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]]
+// CHECK-NEXT: ret i32
uint test_firstbithigh_int(int p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_int2
-// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]]
+// CHECK-NEXT: ret <2 x i32>
uint2 test_firstbithigh_int2(int2 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_int3
-// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]]
+// CHECK-NEXT: ret <3 x i32>
uint3 test_firstbithigh_int3(int3 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_int4
-// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: ret <4 x i32>
uint4 test_firstbithigh_int4(int4 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_long
-// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbitshigh.i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 63, [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1
+// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]]
+// CHECK-NEXT: ret i32
uint test_firstbithigh_long(int64_t p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_long2
-// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 63), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]]
+// CHECK-NEXT: ret <2 x i32>
uint2 test_firstbithigh_long2(int64_t2 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_long3
-// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 63), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]]
+// CHECK-NEXT: ret <3 x i32>
uint3 test_firstbithigh_long3(int64_t3 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_long4
-// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 63), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: ret <4 x i32>
uint4 test_firstbithigh_long4(int64_t4 p0) {
return firstbithigh(p0);
}
// CHECK-LABEL: test_firstbithigh_upcast
-// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}})
-// CHECK: [[CONV:%.*]] = zext <4 x i32> [[FBH]] to <4 x i64>
-// CHECK: ret <4 x i64> [[CONV]]
+// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}})
+// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]]
+// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1)
+// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]]
+// CHECK-NEXT: [[ZEXT:%.*]] = zext <4 x i32> {{.*}} to <4 x i64>
+// CHECK-NEXT: ret <4 x i64> [[ZEXT]]
uint64_t4 test_firstbithigh_upcast(uint4 p0) {
return firstbithigh(p0);
}
diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl b/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
index 7aeb877..b0abaed 100644
--- a/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
@@ -24,4 +24,3 @@ void foo(uint Idx : SV_DispatchThreadID) {}
[shader("compute")]
[numthreads(8,8,1)]
void bar(uint2 Idx : SV_DispatchThreadID) {}
-
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
new file mode 100644
index 0000000..96d5b99
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+
+// CHECK-SPIRV-DAG: @AAA0 = external hidden thread_local addrspace(7) externally_initialized constant float, !spirv.Decorations ![[#METADATA_0:]]
+// CHECK-SPIRV-DAG: @B0 = external hidden thread_local addrspace(7) externally_initialized constant i32, !spirv.Decorations ![[#METADATA_2:]]
+// CHECK-SPIRV-DAG: @CC0 = external hidden thread_local addrspace(7) externally_initialized constant <2 x float>, !spirv.Decorations ![[#METADATA_4:]]
+
+
+// FIXME: replace `float2 c` with a matrix when available.
+void main(float a : AAA, int b : B, float2 c : CC) {
+ float tmp = a + b + c.x + c.y;
+}
+// CHECK-SPIRV: define internal spir_func void @_Z4mainfiDv2_f(float noundef nofpclass(nan inf) %a, i32 noundef %b, <2 x float> noundef nofpclass(nan inf) %c) #0 {
+
+// CHECK: define void @main()
+
+// CHECK-DXIL: %AAA0 = call float @llvm.dx.load.input.f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %B0 = call i32 @llvm.dx.load.input.i32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL %CC0 = call <2 x float> @llvm.dx.load.input.v2f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %AAA0, i32 %B0, <2 x float> %CC0)
+
+// CHECK-SPIRV: %[[#AAA0:]] = load float, ptr addrspace(7) @AAA0, align 4
+// CHECK-SPIRV: %[[#B0:]] = load i32, ptr addrspace(7) @B0, align 4
+// CHECK-SPIRV: %[[#CC0:]] = load <2 x float>, ptr addrspace(7) @CC0, align 8
+// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]]) [ "convergencectrl"(token %0) ]
+
+
+// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]}
+// CHECK-SPIRV-DAG: ![[#METADATA_2]] = !{![[#METADATA_3:]]}
+// CHECK-SPIRV-DAG: ![[#METADATA_4]] = !{![[#METADATA_5:]]}
+
+// CHECK-SPIRV-DAG: ![[#METADATA_1]] = !{i32 30, i32 0}
+// CHECK-SPIRV-DAG: ![[#METADATA_3]] = !{i32 30, i32 1}
+// CHECK-SPIRV-DAG: ![[#METADATA_5]] = !{i32 30, i32 2}
+// | `- Location index
+// `-> Decoration "Location"
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
new file mode 100644
index 0000000..b2cb3da
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+// RUN: %clang_cc1 -triple dxil-px-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+
+struct S0 {
+ float4 position[2];
+ float4 color;
+};
+
+// CHECK: %struct.S0 = type { [2 x <4 x float>], <4 x float> }
+
+// CHECK-SPIRV: @A0 = external hidden thread_local addrspace(7) externally_initialized constant [2 x <4 x float>], !spirv.Decorations ![[#MD_0:]]
+// CHECK-SPIRV: @A2 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]]
+
+// CHECK: define void @main0()
+// CHECK-DXIL: %A0 = call [2 x <4 x float>] @llvm.dx.load.input.a2v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0
+// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1
+
+// CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 16
+// CHECK-SPIRV: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#A0]], 0
+// CHECK-SPIRV: %[[#A2:]] = load <4 x float>, ptr addrspace(7) @A2, align 16
+// CHECK-SPIRV: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %[[#A2]], 1
+
+// CHECK: %[[#ARG:]] = alloca %struct.S0, align 16
+// CHECK: store %struct.S0 %[[#TMP1]], ptr %[[#ARG]], align 16
+// CHECK-DXIL: call void @{{.*}}main0{{.*}}(ptr %[[#ARG]])
+// CHECK-SPIRV: call spir_func void @{{.*}}main0{{.*}}(ptr %[[#ARG]])
+[shader("pixel")]
+void main0(S0 p : A) {
+ float tmp = p.position[0] + p.position[1] + p.color;
+}
+
+// CHECK-SPIRV: ![[#MD_0]] = !{![[#MD_1:]]}
+// CHECK-SPIRV: ![[#MD_1]] = !{i32 30, i32 0}
+// CHECK-SPIRV: ![[#MD_2]] = !{![[#MD_3:]]}
+// CHECK-SPIRV: ![[#MD_3]] = !{i32 30, i32 2}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl
new file mode 100644
index 0000000..733cf3a
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+
+struct S0 {
+ uint Idx : SV_DispatchThreadID;
+};
+
+// CHECK: define void @main0()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#TMP:]] = insertvalue %struct.S0 poison, i32 %[[#ID:]], 0
+// CHECK: %[[#ARG:]] = alloca %struct.S0, align 8
+// CHECK: store %struct.S0 %[[#TMP]], ptr %[[#ARG]], align 4
+// CHECK-DXIL: call void @{{.*}}main0{{.*}}(ptr %[[#ARG]])
+// CHECK-SPIRV: call spir_func void @{{.*}}main0{{.*}}(ptr %[[#ARG]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void main0(S0 p) {}
+
+struct S1 {
+ uint2 a : SV_DispatchThreadID;
+ uint2 b : SV_GroupThreadID;
+};
+
+// CHECK: define void @main1()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#AX_:]] = insertelement <2 x i32> poison, i32 %[[#ID]], i64 0
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 1)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 1)
+// CHECK: %[[#AXY:]] = insertelement <2 x i32> %[[#AX_]], i32 %[[#ID]], i64 1
+// CHECK: %[[#S1A_:]] = insertvalue %struct.S1 poison, <2 x i32> %[[#AXY]], 0
+// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0)
+// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 0)
+// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
+// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1)
+// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 1)
+// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
+// CHECK: %[[#S1AB:]] = insertvalue %struct.S1 %[[#S1A_]], <2 x i32> %[[#ID_XYZ:]], 1
+// CHECK: %[[#ARG:]] = alloca %struct.S1, align 8
+// CHECK: store %struct.S1 %[[#S1AB]], ptr %[[#ARG]], align 8
+// CHECK-DXIL: call void @{{.*}}main1{{.*}}(ptr %[[#ARG]])
+// CHECK-SPIRV: call spir_func void @{{.*}}main1{{.*}}(ptr %[[#ARG]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void main1(S1 p) {}
+
+struct S2C {
+ uint2 b : SV_GroupThreadID;
+};
+
+struct S2 {
+ uint a : SV_DispatchThreadID;
+ S2C child;
+};
+
+// CHECK: define void @main2()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#S2A_:]] = insertvalue %struct.S2 poison, i32 %[[#ID:]], 0
+
+// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0)
+// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 0)
+// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
+// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1)
+// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 1)
+// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
+// CHECK: %[[#S2C:]] = insertvalue %struct.S2C poison, <2 x i32> %[[#ID_XY:]], 0
+
+// CHECK: %[[#S2AB:]] = insertvalue %struct.S2 %[[#S2A_]], %struct.S2C %[[#S2V:]], 1
+// CHECK: %[[#ARG:]] = alloca %struct.S2, align 8
+// CHECK: store %struct.S2 %[[#S2AB]], ptr %[[#ARG]], align 1
+// CHECK-DXIL: call void @{{.*}}main2{{.*}}(ptr %[[#ARG]])
+// CHECK-SPIRV: call spir_func void @{{.*}}main2{{.*}}(ptr %[[#ARG]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void main2(S2 p) {}
diff --git a/clang/test/Driver/HLSL/wconversion.hlsl b/clang/test/Driver/HLSL/wconversion.hlsl
new file mode 100644
index 0000000..1857a3d
--- /dev/null
+++ b/clang/test/Driver/HLSL/wconversion.hlsl
@@ -0,0 +1,7 @@
+// RUN: %clang_dxc -T lib_6_7 %s -### %s 2>&1 | FileCheck %s --check-prefixes=CONV
+// RUN: %clang_dxc -T lib_6_7 -Wno-conversion %s -### %s 2>&1 | FileCheck %s --check-prefixes=NOCONV
+
+// make sure we generate -Wconversion by default
+// CONV: "-Wconversion"
+// make sure -Wno-conversion still works
+// NOCONV: "-Wno-conversion"
diff --git a/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1250.bc b/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1250.bc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1250.bc
diff --git a/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1251.bc b/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1251.bc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/oclc_isa_version_1251.bc
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index 914e018..10d6498 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -22,10 +22,14 @@
// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSAN,GPUSAN,SAN %s
-// ASan enabled for multiple amdgpu-arch [gfx908:xnack+,gfx900:xnack+]
+// GPU ASan enabled for multiple amdgpu-arch [gfx908:xnack+,gfx900:xnack+]
// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack+ -fsanitize=address -fgpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSAN,GPUSAN,SAN %s
+// GPU ASan enabled for amdgpu-arch [gfx1250,gfx1251]
+// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx1250,gfx1251 -fsanitize=address -fgpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=HOSTSAN,GPUSAN,SAN %s
+
// GPU ASan Disabled Test Cases
// GPU ASan disabled through '-fsanitize=address' without '-fgpu-sanitize' flag for amdgpu-arch [gfx908]
@@ -56,9 +60,9 @@
// HOSTSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "c".*}}
-// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-mlink-bitcode-file" "[^"]*asanrtl.bc".* "-mlink-bitcode-file" "[^"]*ockl.bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-fsanitize=address".* "-x" "c".*}}
+// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-mlink-bitcode-file" "[^"]*asanrtl.bc".* "-mlink-bitcode-file" "[^"]*ockl.bc".* "-target-cpu" "(gfx908|gfx900|gfx1250|gfx1251)".* "-fopenmp".* "-fsanitize=address".* "-x" "c".*}}
// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-x" "c".*}}
-// SAN: {{"[^"]*llvm-offload-binary[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=gfx908(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}}
+// SAN: {{"[^"]*llvm-offload-binary[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=(gfx908|gfx1250|gfx1251)(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}}
// SAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "ir".*}}
// SAN: {{"[^"]*clang-linker-wrapper[^"]*".* "--host-triple=x86_64-unknown-linux-gnu".* "--linker-path=[^"]*".* "--whole-archive" "[^"]*(libclang_rt.asan_static.a|libclang_rt.asan_static-x86_64.a)".* "--whole-archive" "[^"]*(libclang_rt.asan.a|libclang_rt.asan-x86_64.a)".*}}
diff --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip
index 0c9c15b..4903851 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -3,6 +3,11 @@
// RUN: -nogpuinc --rocm-path=%S/Inputs/rocm \
// RUN: %s 2>&1 | FileCheck -check-prefixes=NORDC %s
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx1250,gfx1251 \
+// RUN: -fsanitize=address \
+// RUN: -nogpuinc --rocm-path=%S/Inputs/rocm \
+// RUN: %s 2>&1 | FileCheck -check-prefixes=NORDC %s
+
// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
// RUN: -fsanitize=address -fno-gpu-sanitize \
// RUN: -nogpuinc --rocm-path=%S/Inputs/rocm \
diff --git a/clang/test/Driver/rocm-device-libs.cl b/clang/test/Driver/rocm-device-libs.cl
index f9766e6..649dc85 100644
--- a/clang/test/Driver/rocm-device-libs.cl
+++ b/clang/test/Driver/rocm-device-libs.cl
@@ -139,6 +139,18 @@
// RUN: 2>&1 | FileCheck --check-prefixes=ASAN,COMMON %s
// RUN: %clang -### -target amdgcn-amd-amdhsa \
+// RUN: -x cl -mcpu=gfx1250 -fsanitize=address \
+// RUN: --rocm-path=%S/Inputs/rocm \
+// RUN: %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ASAN,COMMON %s
+
+// RUN: %clang -### -target amdgcn-amd-amdhsa \
+// RUN: -x cl -mcpu=gfx1251 -fsanitize=address \
+// RUN: --rocm-path=%S/Inputs/rocm \
+// RUN: %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ASAN,COMMON %s
+
+// RUN: %clang -### -target amdgcn-amd-amdhsa \
// RUN: -x cl -mcpu=gfx908:xnack+ \
// RUN: --rocm-path=%S/Inputs/rocm \
// RUN: %s \
diff --git a/clang/test/Parser/lambda-misplaced-capture-default.cpp b/clang/test/Parser/lambda-misplaced-capture-default.cpp
index d65b875..4f5bd6d 100644
--- a/clang/test/Parser/lambda-misplaced-capture-default.cpp
+++ b/clang/test/Parser/lambda-misplaced-capture-default.cpp
@@ -36,3 +36,12 @@ template <typename... Args> void Test(Args... args) {
[... xs = &args, &] {}; // expected-error {{capture default must be first}}
}
} // namespace misplaced_capture_default_pack
+
+namespace GH163498 {
+struct S {
+ template <class T> S(T) {}
+};
+void t() {
+ S s{[a(42), &] {}}; // expected-error {{capture default must be first}}
+}
+}
diff --git a/clang/test/ParserHLSL/semantic_parsing.hlsl b/clang/test/ParserHLSL/semantic_parsing.hlsl
index 726dead..bff7bd0 100644
--- a/clang/test/ParserHLSL/semantic_parsing.hlsl
+++ b/clang/test/ParserHLSL/semantic_parsing.hlsl
@@ -12,30 +12,33 @@ void Pony(int GI : SV_IWantAPony) { }
// expected-note@+1 {{to match this '('}}
void SuperPony(int GI : 0) { }
-// expected-error@+1 {{unknown HLSL semantic '_'}}
+// '_' is a valid CPP identifier.
void MegaPony(int GI : _) { }
-// expected-error@+1 {{unknown HLSL semantic 'A0A'}}
+void GarguantuanPony(int GI : _1) { }
+
void CoolPony(int GI : A0A0) { }
-// expected-error@+1 {{unknown HLSL semantic 'A_'}}
void NicePony(int GI : A_0) { }
-// expected-error@+1 {{unknown HLSL semantic 'A'}}
void CutePony(int GI : A00) { }
-// expected-error@+3 {{unknown HLSL semantic 'A'}}
// expected-error@+2 {{expected ')'}}
// expected-note@+1 {{to match this '('}}
void DoublePony(int GI : A00 B) { }
-// expected-error@+1 {{unknown HLSL semantic 'é'}}
-void BigPony(int GI : é) { }
+// Unicode can be used:
+// https://timsong-cpp.github.io/cppwp/n3337/charname.allowed
+void FrenchPony(int GI : garçon_de_café) { }
+void UnicodePony(int GI : ℮) { }
+
+// Since P1949 seems Emojis are not allowed, even if in the range
+// mentioned in N3337.
+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1949r7.html
// expected-error@+2 {{unexpected character <U+1F60A>}}
// expected-error@+1 {{expected HLSL Semantic identifier}}
void UTFPony(int GI : 😊) { }
-// expected-error@+2 {{character <U+1F60A> not allowed in an identifier}}
-// expected-error@+1 {{unknown HLSL semantic 'PonyWithA😊'}}
+// expected-error@+1 {{character <U+1F60A> not allowed in an identifier}}
void SmilingPony(int GI : PonyWithA😊) { }
diff --git a/clang/test/Profile/Inputs/c-counter-overflows.proftext b/clang/test/Profile/Inputs/c-counter-overflows.proftext
index 4d0287c..8633060 100644
--- a/clang/test/Profile/Inputs/c-counter-overflows.proftext
+++ b/clang/test/Profile/Inputs/c-counter-overflows.proftext
@@ -1,5 +1,5 @@
main
-7779561829442898616
+862032801801816760
8
1
68719476720
diff --git a/clang/test/Profile/Inputs/c-general.profdata.v12 b/clang/test/Profile/Inputs/c-general.profdata.v12
new file mode 100644
index 0000000..57a72fa
--- /dev/null
+++ b/clang/test/Profile/Inputs/c-general.profdata.v12
Binary files differ
diff --git a/clang/test/Profile/Inputs/c-general.proftext b/clang/test/Profile/Inputs/c-general.proftext
index 08280ef..72e1be6 100644
--- a/clang/test/Profile/Inputs/c-general.proftext
+++ b/clang/test/Profile/Inputs/c-general.proftext
@@ -7,7 +7,7 @@ simple_loops
75
conditionals
-4904767535850050386
+293081517422662482
13
1
100
@@ -24,7 +24,7 @@ conditionals
1
early_exits
-2880354649761471549
+574511640547777597
9
1
0
@@ -37,7 +37,7 @@ early_exits
0
jumps
-15051420506203462683
+63440946314451995
22
1
1
@@ -86,7 +86,7 @@ switches
0
big_switch
-13144136522122330070
+461999971447013334
17
1
32
@@ -125,7 +125,7 @@ boolean_operators
33
boolop_loops
-12402604614320574815
+873389568252105055
13
1
50
@@ -149,7 +149,7 @@ conditional_operator
1
do_fallthrough
-8714614136504380050
+644163604256451218
4
1
10
diff --git a/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext b/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext
index d880663..7af5097 100644
--- a/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext
+++ b/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext
@@ -1,5 +1,5 @@
never_called
-6820425066224770721
+1055817543190535841
9
0
0
@@ -17,7 +17,7 @@ main
1
dead_code
-5254464978620792806
+642778960193404902
10
1
0
diff --git a/clang/test/Profile/Inputs/cxx-rangefor.proftext b/clang/test/Profile/Inputs/cxx-rangefor.proftext
index d41205b..cfc88da 100644
--- a/clang/test/Profile/Inputs/cxx-rangefor.proftext
+++ b/clang/test/Profile/Inputs/cxx-rangefor.proftext
@@ -1,5 +1,5 @@
_Z9range_forv
-8789831523895825398
+719380991647896566
5
1
4
diff --git a/clang/test/Profile/Inputs/cxx-throws.proftext b/clang/test/Profile/Inputs/cxx-throws.proftext
index 043dea0..92b0eab 100644
--- a/clang/test/Profile/Inputs/cxx-throws.proftext
+++ b/clang/test/Profile/Inputs/cxx-throws.proftext
@@ -1,5 +1,5 @@
_Z6throwsv
-18172607911962830854
+878785342860126214
9
1
100
diff --git a/clang/test/Profile/Inputs/misexpect-switch-default.proftext b/clang/test/Profile/Inputs/misexpect-switch-default.proftext
index 533da91..112426e 100644
--- a/clang/test/Profile/Inputs/misexpect-switch-default.proftext
+++ b/clang/test/Profile/Inputs/misexpect-switch-default.proftext
@@ -1,6 +1,6 @@
main
# Func Hash:
-8734802134600123338
+664351602352194506
# Num Counters:
9
# Counter Values:
diff --git a/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext b/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext
index 0da9379..99d067c 100644
--- a/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext
+++ b/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext
@@ -1,6 +1,6 @@
main
# Func Hash:
-3721743393642630379
+262978879822089451
# Num Counters:
10
# Counter Values:
diff --git a/clang/test/Profile/c-collision.c b/clang/test/Profile/c-collision.c
index 6c779c6..f35ba1b 100644
--- a/clang/test/Profile/c-collision.c
+++ b/clang/test/Profile/c-collision.c
@@ -2,8 +2,8 @@
// RUN: %clang_cc1 -UEXTRA -triple x86_64-unknown-linux-gnu -main-file-name c-collision.c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s --check-prefix=CHECK-NOEXTRA
// RUN: %clang_cc1 -DEXTRA -triple x86_64-unknown-linux-gnu -main-file-name c-collision.c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s --check-prefix=CHECK-EXTRA
-// CHECK-NOEXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 7156072912471487002,
-// CHECK-EXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 -4383447408116050035,
+// CHECK-NOEXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 238543884830405146,
+// CHECK-EXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 228238610311337869,
extern int bar;
void foo(void) {
diff --git a/clang/test/Profile/c-general.c b/clang/test/Profile/c-general.c
index ee36a43..6c865e6 100644
--- a/clang/test/Profile/c-general.c
+++ b/clang/test/Profile/c-general.c
@@ -4,6 +4,7 @@
// RUN: llvm-profdata merge %S/Inputs/c-general.proftext -o %t.profdata
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%t.profdata | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v12 | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v5 | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v3 | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s
// Also check compatibility with older profiles.
diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp
index f665b1b..3a1da3b 100644
--- a/clang/test/SemaCXX/attr-mode-tmpl.cpp
+++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp
@@ -45,7 +45,7 @@ void CheckMachineMode() {
// Check attributes on function parameters.
template <class T1, class T2>
-void CheckParameters(T1 __attribute__((mode(SI))) paramSI, // expected-note{{ignored: substitution failure}} expected-note-re{{not viable: no known conversion from '{{.*}}' (vector of 4 '{{.*}}' values) to 'EnumType' for 2nd argument}}
+void CheckParameters(T1 __attribute__((mode(SI))) paramSI, // expected-note{{ignored: substitution failure}} expected-note{{ignored: substitution failure [with T1 = int, T2 = int]: type of machine mode does not match type of base type}}
T1 __attribute__((mode(V4DI))) paramV4DI, // expected-warning{{deprecated}}
T2 __attribute__((mode(SF))) paramSF,
T2 __attribute__((mode(V4DF))) paramV4DF) { // expected-warning{{deprecated}}
diff --git a/clang/test/SemaCXX/cxx23-assume.cpp b/clang/test/SemaCXX/cxx23-assume.cpp
index ce86266..a594a1a 100644
--- a/clang/test/SemaCXX/cxx23-assume.cpp
+++ b/clang/test/SemaCXX/cxx23-assume.cpp
@@ -108,7 +108,8 @@ constexpr bool f4() {
template <typename T>
concept C = f4<T>(); // expected-note 3 {{in instantiation of}}
// expected-note@-1 3 {{while substituting}}
- // expected-error@-2 2 {{resulted in a non-constant expression}}
+ // expected-error@-2 {{resulted in a non-constant expression}}
+ // expected-note@-3 {{because substituted constraint expression is ill-formed: substitution into constraint expression resulted in a non-constant expression}}
struct D {
int x;
@@ -130,13 +131,13 @@ constexpr int f5() requires C<T> { return 1; } // expected-note {{while checking
// expected-note@-1 {{candidate template ignored}}
template <typename T>
-constexpr int f5() requires (!C<T>) { return 2; } // expected-note 4 {{while checking the satisfaction}} \
- // expected-note 4 {{while substituting template arguments}} \
+constexpr int f5() requires (!C<T>) { return 2; } // expected-note 3 {{while checking the satisfaction}} \
+ // expected-note 3 {{while substituting template arguments}} \
// expected-note {{candidate template ignored}}
static_assert(f5<int>() == 1);
-static_assert(f5<D>() == 1); // expected-note 3 {{while checking constraint satisfaction}}
- // expected-note@-1 3 {{while substituting deduced template arguments}}
+static_assert(f5<D>() == 1); // expected-note 2 {{while checking constraint satisfaction}}
+ // expected-note@-1 2 {{while substituting deduced template arguments}}
// expected-error@-2 {{no matching function for call}}
static_assert(f5<double>() == 2);
@@ -170,7 +171,7 @@ foo (int x, int y)
// Do not crash when assumptions are unreachable.
namespace gh106898 {
-int foo () {
+int foo () {
while(1);
int a = 0, b = 1;
__attribute__((assume (a < b)));
diff --git a/clang/test/SemaCXX/cxx2b-warn-shadow.cpp b/clang/test/SemaCXX/cxx2b-warn-shadow.cpp
index 76866c4..9ce0c5a 100644
--- a/clang/test/SemaCXX/cxx2b-warn-shadow.cpp
+++ b/clang/test/SemaCXX/cxx2b-warn-shadow.cpp
@@ -11,3 +11,29 @@ struct Foo {
}
};
} // namespace GH95707
+
+namespace GH163731 {
+struct S1 {
+ int a;
+ void m(this S1 &self) {
+ auto lambda = [](int a) { return a; };
+ }
+};
+
+struct S2 {
+ int a;
+ void m(this S2 &self) {
+ int a = 1; // expected-note {{previous declaration is here}}
+ auto lambda = [](int a) { // expected-warning {{declaration shadows a local variable}}
+ return a;
+ };
+ }
+};
+
+struct S3 {
+ int a;
+ void m(this S3 &self) {
+ auto lambda = [self](int a) { return a + self.a; };
+ }
+};
+}
diff --git a/clang/test/SemaCXX/dependent-switch-case.cpp b/clang/test/SemaCXX/dependent-switch-case.cpp
new file mode 100644
index 0000000..bbeab3a
--- /dev/null
+++ b/clang/test/SemaCXX/dependent-switch-case.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+// RUN: %clang_cc1 -std=c++20 %s -verify -fexperimental-new-constant-interpreter
+
+constexpr bool e(int){switch(0)0=0:return t(;} // expected-error {{expression is not assignable}} \
+ // expected-error {{expected 'case' keyword before expression}} \
+ // expected-error {{expected expression}}
diff --git a/clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
index f99e606..1f70186 100644
--- a/clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/firstbithigh-errors.hlsl
@@ -12,7 +12,7 @@ int test_too_many_arg(int p0) {
double test_int_builtin(double p0) {
return firstbithigh(p0);
- // expected-error@-1 {{call to 'firstbithigh' is ambiguous}}
+ // expected-error@-1 {{no matching function for call to 'firstbithigh'}}
}
double2 test_int_builtin_2(double2 p0) {
diff --git a/clang/test/SemaHLSL/Semantics/semantics-invalid.hlsl b/clang/test/SemaHLSL/Semantics/semantics-invalid.hlsl
new file mode 100644
index 0000000..fdba6f6
--- /dev/null
+++ b/clang/test/SemaHLSL/Semantics/semantics-invalid.hlsl
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -hlsl-entry main -verify %s
+
+typedef float t_f : SEMANTIC; // expected-warning{{'SEMANTIC' attribute only applies to parameters, non-static data members, and functions}}
+
+struct semantic_on_struct : SEMANTIC { // expected-error{{expected class name}}
+ float a;
+};
+
+struct s_fields_multiple_semantics {
+ float a : semantic_a : semantic_c; // expected-error{{use of undeclared identifier 'semantic_c'}}
+ float b : semantic_b;
+};
+
+[numthreads(1, 1, 1)]
+void main() {
+ float a : SEM_A; // expected-warning{{'SEM_A' attribute only applies to parameters, non-static data members, and functions}}
+}
diff --git a/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl b/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl
new file mode 100644
index 0000000..1e6bae4
--- /dev/null
+++ b/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -hlsl-entry CSMain -x hlsl -finclude-default-header -ast-dump -o - %s | FileCheck %s
+
+struct s_fields {
+ float a : semantic_a;
+ float b : semantic_b;
+// CHECK: |-CXXRecordDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-3]]:8 struct s_fields definition
+// CHECK: | |-FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:9 a 'float'
+// CHECK: | | `-HLSLUserSemanticAttr 0x{{[0-9a-fA-F]+}} <col:13>
+// CHECK: | `-FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:9 b 'float'
+// CHECK: | `-HLSLUserSemanticAttr 0x{{[0-9a-fA-F]+}} <col:13>
+};
+
+float fn_foo1(float a : a, float b : b) : sem_ret { return 1.0f; }
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}> col:7 fn_foo1 'float (float, float)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <{{.*}}> col:21 a 'float'
+// CHECK-NEXT: | | `-HLSLUserSemanticAttr {{.*}} <{{.*}}>
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <{{.*}}> col:34 b 'float'
+// CHECK-NEXT: | | `-HLSLUserSemanticAttr {{.*}} <{{.*}}>
+// CHECK-NEXT: | |-CompoundStmt {{.*}} <{{.*}}>
+// CHECK-NEXT: | | `-ReturnStmt {{.*}} <{{.*}}>
+// CHECK-NEXT: | | `-FloatingLiteral {{.*}} <{{.*}}> 'float' 1.000000e+00
+// CHECK-NEXT: | `-HLSLUserSemanticAttr {{.*}} <{{.*}}>
+float fn_foo2(float a : a, float b : b) : sem_ret : also_ret { return 1.0f; }
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}> col:7 fn_foo2 'float (float, float)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <{{.*}}> col:21 a 'float'
+// CHECK-NEXT: | `-HLSLUserSemanticAttr {{.*}} <{{.*}}>
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <{{.*}}> col:34 b 'float'
+// CHECK-NEXT: | `-HLSLUserSemanticAttr {{.*}} <{{.*}}>
+// CHECK-NEXT: |-CompoundStmt {{.*}} <{{.*}}>
+// CHECK-NEXT: | `-ReturnStmt {{.*}} <{{.*}}>
+// CHECK-NEXT: | `-FloatingLiteral {{.*}} <{{.*}}> 'float' 1.000000e+00
+// CHECK-NEXT: |-HLSLUserSemanticAttr {{.*}} <{{.*}}>
+// CHECK-NEXT: `-HLSLUserSemanticAttr {{.*}} <{{.*}}>
diff --git a/clang/test/SemaHLSL/Types/AggregateSplatConstantExpr.hlsl b/clang/test/SemaHLSL/Types/AggregateSplatConstantExpr.hlsl
new file mode 100644
index 0000000..630acd8
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/AggregateSplatConstantExpr.hlsl
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -fnative-int16-type -std=hlsl202x -verify %s
+
+// expected-no-diagnostics
+
+struct Base {
+ double D;
+ uint64_t2 U;
+ int16_t I : 5;
+ uint16_t I2: 5;
+};
+
+struct R : Base {
+ int G : 10;
+ int : 30;
+ float F;
+};
+
+struct B1 {
+ float A;
+ float B;
+};
+
+struct B2 : B1 {
+ int C;
+ int D;
+ bool BB;
+};
+
+// tests for HLSLAggregateSplatCast
+export void fn() {
+ // result type vector
+ // splat from a vector of size 1
+
+ constexpr float1 Y = {1.0};
+ constexpr float4 F4 = (float4)Y;
+ _Static_assert(F4[0] == 1.0, "Woo!");
+ _Static_assert(F4[1] == 1.0, "Woo!");
+ _Static_assert(F4[2] == 1.0, "Woo!");
+ _Static_assert(F4[3] == 1.0, "Woo!");
+
+ // result type array
+ // splat from a scalar
+ constexpr float F = 3.33;
+ constexpr int B6[6] = (int[6])F;
+ _Static_assert(B6[0] == 3, "Woo!");
+ _Static_assert(B6[1] == 3, "Woo!");
+ _Static_assert(B6[2] == 3, "Woo!");
+ _Static_assert(B6[3] == 3, "Woo!");
+ _Static_assert(B6[4] == 3, "Woo!");
+ _Static_assert(B6[5] == 3, "Woo!");
+
+ // splat from a vector of size 1
+ constexpr int1 A1 = {1};
+ constexpr uint64_t2 A7[2] = (uint64_t2[2])A1;
+ _Static_assert(A7[0][0] == 1, "Woo!");
+ _Static_assert(A7[0][1] == 1, "Woo!");
+ _Static_assert(A7[1][0] == 1, "Woo!");
+ _Static_assert(A7[1][1] == 1, "Woo!");
+
+ // result type struct
+ // splat from a scalar
+ constexpr double D = 97.6789;
+ constexpr R SR = (R)(D + 3.0);
+ _Static_assert(SR.D == 100.6789, "Woo!");
+ _Static_assert(SR.U[0] == 100, "Woo!");
+ _Static_assert(SR.U[1] == 100, "Woo!");
+ _Static_assert(SR.I == 4, "Woo!");
+ _Static_assert(SR.I2 == 4, "Woo!");
+ _Static_assert(SR.G == 100, "Woo!");
+ _Static_assert(SR.F == 100.6789, "Woo!");
+
+ // splat from a vector of size 1
+ constexpr float1 A100 = {1000.1111};
+ constexpr B2 SB2 = (B2)A100;
+ _Static_assert(SB2.A == 1000.1111, "Woo!");
+ _Static_assert(SB2.B == 1000.1111, "Woo!");
+ _Static_assert(SB2.C == 1000, "Woo!");
+ _Static_assert(SB2.D == 1000, "Woo!");
+ _Static_assert(SB2.BB == true, "Woo!");
+
+ // splat from a bool to an int and float etc
+ constexpr bool B = true;
+ constexpr B2 SB3 = (B2)B;
+ _Static_assert(SB3.A == 1.0, "Woo!");
+ _Static_assert(SB3.B == 1.0, "Woo!");
+ _Static_assert(SB3.C == 1, "Woo!");
+ _Static_assert(SB3.D == 1, "Woo!");
+ _Static_assert(SB3.BB == true, "Woo!");
+}
diff --git a/clang/test/SemaHLSL/Types/ElementwiseCastConstantExpr.hlsl b/clang/test/SemaHLSL/Types/ElementwiseCastConstantExpr.hlsl
new file mode 100644
index 0000000..c9963c3
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/ElementwiseCastConstantExpr.hlsl
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -fnative-int16-type -std=hlsl202x -verify %s
+
+// expected-no-diagnostics
+
+struct Base {
+ double D;
+ uint64_t2 U;
+ int16_t I : 5;
+ uint16_t I2: 5;
+};
+
+struct R : Base {
+ int G : 10;
+ int : 30;
+ float F;
+};
+
+struct B1 {
+ float A;
+ float B;
+};
+
+struct B2 : B1 {
+ int C;
+ int D;
+ bool BB;
+};
+
+export void fn() {
+ _Static_assert(((float4)(int[6]){1,2,3,4,5,6}).x == 1.0, "Woo!");
+
+ // This compiling successfully verifies that the array constant expression
+ // gets truncated to a float at compile time for instantiation via the
+ // flat cast
+ _Static_assert(((int)(int[2]){1,2}) == 1, "Woo!");
+
+ // truncation tests
+ // result type int
+ // truncate from struct
+ constexpr B1 SB1 = {1.0, 3.0};
+ constexpr int X = (int)SB1;
+ _Static_assert(X == 1, "Woo!");
+
+ // result type float
+ // truncate from array
+ constexpr B1 Arr[2] = {4.0, 3.0, 2.0, 1.0};
+ constexpr float F = (float)Arr;
+ _Static_assert(F == 4.0, "Woo!");
+
+ // result type vector
+ // truncate from array of vector
+ constexpr int2 Arr2[2] = {5,6,7,8};
+ constexpr int2 I2 = (int2)Arr2;
+ _Static_assert(I2[0] == 5, "Woo!");
+ _Static_assert(I2[1] == 6, "Woo!");
+
+ // lhs and rhs are same "size" tests
+
+ // result type vector from array
+ constexpr int4 I4 = (int4)Arr;
+ _Static_assert(I4[0] == 4, "Woo!");
+ _Static_assert(I4[1] == 3, "Woo!");
+ _Static_assert(I4[2] == 2, "Woo!");
+ _Static_assert(I4[3] == 1, "Woo!");
+
+ // result type array from vector
+ constexpr double3 D3 = {100.11, 200.11, 300.11};
+ constexpr float FArr[3] = (float[3])D3;
+ _Static_assert(FArr[0] == 100.11, "Woo!");
+ _Static_assert(FArr[1] == 200.11, "Woo!");
+ _Static_assert(FArr[2] == 300.11, "Woo!");
+
+ // result type struct from struct
+ constexpr B2 SB2 = {5.5, 6.5, 1000, 5000, false};
+ constexpr Base SB = (Base)SB2;
+ _Static_assert(SB.D == 5.5, "Woo!");
+ _Static_assert(SB.U[0] == 6, "Woo!");
+ _Static_assert(SB.U[1] == 1000, "Woo!");
+ _Static_assert(SB.I == 8, "Woo!");
+ _Static_assert(SB.I2 == 0, "Woo!");
+
+ // Make sure we read bitfields correctly
+ constexpr Base BB = {222.22, {100, 200}, -2, 7};
+ constexpr int Arr3[5] = (int[5])BB;
+ _Static_assert(Arr3[0] == 222, "Woo!");
+ _Static_assert(Arr3[1] == 100, "Woo!");
+ _Static_assert(Arr3[2] == 200, "Woo!");
+ _Static_assert(Arr3[3] == -2, "Woo!");
+ _Static_assert(Arr3[4] == 7, "Woo!");
+}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 7d2a010..bd0bf3c 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -173,8 +173,7 @@ namespace pr6249 {
}
namespace PR6723 {
- template<unsigned char C> void f(int (&a)[C]); // expected-note 3{{candidate template ignored: substitution failure [with C = '\x00']}}
- // expected-note@-1 {{not viable: no known conversion from 'int[512]' to 'int (&)[0]'}}
+ template<unsigned char C> void f(int (&a)[C]); // expected-note 4{{candidate template ignored: substitution failure [with C = '\x00']}}
void g() {
int arr512[512];
f(arr512); // expected-error{{no matching function for call}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 5752cba..45bdb4c 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -43,7 +43,7 @@ void TempFunc() {}
void Useage() {
//expected-error@+2 {{no matching function}}
- //expected-note@-4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b'}}
+ //expected-note@-4 {{candidate template ignored: substitution failure [with a = 1, b = 4294967295, c = 1]: non-type template argument evaluates to -1, which cannot be narrowed to type 'unsigned int'}}
TempFunc<1, -1, 1>();
}
}