| // 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); |
| } |