|
1 | 1 | // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s |
2 | 2 |
|
3 | | -// CHECK-LABEL: fn |
4 | | -// CHECK: [[B:%.*]] = alloca <2 x i32>, align 1 |
5 | | -// CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[B]], align 1 |
6 | | -// CHECK-NEXT: [[BoolVec:%.*]] = load <2 x i32>, ptr [[B]], align 1 |
| 3 | +// CHECK: %struct.S = type { <2 x i32>, float } |
| 4 | +// CHECK: [[ConstS:@.*]] = private unnamed_addr constant %struct.S { <2 x i32> splat (i32 1), float 1.000000e+00 }, align 8 |
| 5 | +struct S { |
| 6 | + bool2 bv; |
| 7 | + float f; |
| 8 | +}; |
| 9 | + |
| 10 | +// CHECK-LABEL: define noundef i1 {{.*}}fn1{{.*}} |
| 11 | +// CHECK: [[B:%.*]] = alloca <2 x i32>, align 8 |
| 12 | +// CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[B]], align 8 |
| 13 | +// CHECK-NEXT: [[BoolVec:%.*]] = load <2 x i32>, ptr [[B]], align 8 |
7 | 14 | // CHECK-NEXT: [[L:%.*]] = trunc <2 x i32> [[BoolVec:%.*]] to <2 x i1> |
8 | 15 | // CHECK-NEXT: [[VecExt:%.*]] = extractelement <2 x i1> [[L]], i32 0 |
9 | 16 | // CHECK-NEXT: ret i1 [[VecExt]] |
10 | | -bool fn() { |
| 17 | +bool fn1() { |
11 | 18 | bool2 B = {true,true}; |
12 | 19 | return B[0]; |
13 | 20 | } |
14 | 21 |
|
15 | | -// CHECK-LABEL: fn2 |
| 22 | +// CHECK-LABEL: define noundef <2 x i1> {{.*}}fn2{{.*}} |
16 | 23 | // CHECK: [[VAddr:%.*]] = alloca i32, align 4 |
17 | | -// CHECK-NEXT: [[A:%.*]] = alloca <2 x i32>, align 1 |
| 24 | +// CHECK-NEXT: [[A:%.*]] = alloca <2 x i32>, align 8 |
18 | 25 | // CHECK-NEXT: [[StoreV:%.*]] = zext i1 {{.*}} to i32 |
19 | 26 | // CHECK-NEXT: store i32 [[StoreV]], ptr [[VAddr]], align 4 |
20 | 27 | // CHECK-NEXT: [[L:%.*]] = load i32, ptr [[VAddr]], align 4 |
21 | 28 | // CHECK-NEXT: [[LoadV:%.*]] = trunc i32 [[L]] to i1 |
22 | 29 | // CHECK-NEXT: [[Vec:%.*]] = insertelement <2 x i1> poison, i1 [[LoadV]], i32 0 |
23 | 30 | // CHECK-NEXT: [[Vec1:%.*]] = insertelement <2 x i1> [[Vec]], i1 true, i32 1 |
24 | 31 | // CHECK-NEXT: [[Z:%.*]] = zext <2 x i1> [[Vec1]] to <2 x i32> |
25 | | -// CHECK-NEXT: store <2 x i32> [[Z]], ptr [[A]], align 1 |
26 | | -// CHECK-NEXT: [[LoadBV:%.*]] = load <2 x i32>, ptr [[A]], align 1 |
| 32 | +// CHECK-NEXT: store <2 x i32> [[Z]], ptr [[A]], align 8 |
| 33 | +// CHECK-NEXT: [[LoadBV:%.*]] = load <2 x i32>, ptr [[A]], align 8 |
27 | 34 | // CHECK-NEXT: [[LoadV2:%.*]] = trunc <2 x i32> [[LoadBV]] to <2 x i1> |
28 | 35 | // CHECK-NEXT: ret <2 x i1> [[LoadV2]] |
29 | 36 | bool2 fn2(bool V) { |
30 | 37 | bool2 A = {V,true}; |
31 | 38 | return A; |
32 | 39 | } |
| 40 | + |
| 41 | +// CHECK-LABEL: define noundef i1 {{.*}}fn3{{.*}} |
| 42 | +// CHECK: [[s:%.*]] = alloca %struct.S, align 8 |
| 43 | +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[s]], ptr align 8 [[ConstS]], i32 16, i1 false) |
| 44 | +// CHECK-NEXT: [[BV:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[s]], i32 0, i32 0 |
| 45 | +// CHECK-NEXT: [[LBV:%.*]] = load <2 x i32>, ptr [[BV]], align 8 |
| 46 | +// CHECK-NEXT: [[LV:%.*]] = trunc <2 x i32> [[LBV]] to <2 x i1> |
| 47 | +// CHECK-NEXT: [[VX:%.*]] = extractelement <2 x i1> [[LV]], i32 0 |
| 48 | +// CHECK-NEXT: ret i1 [[VX]] |
| 49 | +bool fn3() { |
| 50 | + S s = {{true,true}, 1.0}; |
| 51 | + return s.bv[0]; |
| 52 | +} |
0 commit comments