blob: 620e2624f31b72f7d4d3fc025c13e8734169cda3 [file] [edit]
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
struct P {
float a;
};
struct S : P {
double b;
int c[2];
};
// CHECK-LABEL: define hidden void @_Z5case11S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[SLOCAL:%.*]] = alloca [[STRUCT_S:%.*]], align 1
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[SLOCAL]], ptr align 1 [[S]], i32 20, i1 false)
// CHECK-NEXT: ret void
//
void case1(S s) {
// struct initialization
S sLocal = s;
}
// CHECK-LABEL: define hidden void @_Z5case21S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[SLOCAL:%.*]] = alloca [[STRUCT_S:%.*]], align 1
// CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_S]], align 1
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[SLOCAL]], ptr align 1 [[S]], i32 20, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP]], ptr align 1 [[SLOCAL]], i32 20, i1 false)
// CHECK-NEXT: ret void
//
void case2(S s) {
S sLocal;
// struct assignment
sLocal = s;
}
// CHECK-LABEL: define hidden void @_Z4useS1S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: ret void
//
void useS(S s) {}
// CHECK-LABEL: define hidden void @_Z5case31S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[BYVAL_TEMP:%.*]] = alloca [[STRUCT_S:%.*]], align 1
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[BYVAL_TEMP]], ptr align 1 [[S]], i32 20, i1 false)
// CHECK-NEXT: call void @_Z4useS1S(ptr noundef align 1 dead_on_return [[BYVAL_TEMP]]) #[[ATTR3:[0-9]+]] [ "convergencectrl"(token [[TMP0]]) ]
// CHECK-NEXT: ret void
//
void case3(S s) {
// struct argument passing
useS(s);
}
// CHECK-LABEL: define hidden void @_Z5case41S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[PLOCAL:%.*]] = alloca [[STRUCT_P:%.*]], align 1
// CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 1
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP]], ptr align 1 [[S]], i32 20, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[PLOCAL]], ptr align 1 [[TMP]], i32 4, i1 false)
// CHECK-NEXT: ret void
//
void case4(S s) {
// derived to base conversion in initialization
P pLocal = s;
}
// CHECK-LABEL: define hidden void @_Z5case51S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[P:%.*]] = alloca [[STRUCT_P:%.*]], align 1
// CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_P]], align 1
// CHECK-NEXT: [[TMP1:%.*]] = alloca [[STRUCT_S:%.*]], align 1
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP1]], ptr align 1 [[S]], i32 20, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[P]], ptr align 1 [[TMP1]], i32 4, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP]], ptr align 1 [[P]], i32 4, i1 false)
// CHECK-NEXT: ret void
//
void case5(S s) {
P p;
// derived to base conversion in assignment
p = s;
}
// CHECK-LABEL: define hidden void @_Z4useP1P(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[P:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[P_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: store ptr [[P]], ptr [[P_INDIRECT_ADDR]], align 4
// CHECK-NEXT: ret void
//
void useP(P p) {}
// CHECK-LABEL: define hidden void @_Z5case61S(
// CHECK-SAME: ptr noundef align 1 dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_P:%.*]], align 1
// CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 1
// CHECK-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP]], ptr align 1 [[S]], i32 20, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TMP]], ptr align 1 [[TMP]], i32 4, i1 false)
// CHECK-NEXT: call void @_Z4useP1P(ptr noundef align 1 dead_on_return [[AGG_TMP]]) #[[ATTR3]] [ "convergencectrl"(token [[TMP0]]) ]
// CHECK-NEXT: ret void
//
void case6(S s) {
// derived to base conversion in argument passing
useP(s);
}