Skip to content

Commit 793541d

Browse files
committed
test with struct that contains bool vector. make sure bool vector in struct is a vector of i32. make sure constant struct has vector of i32
make clang format happy
1 parent 2e534a5 commit 793541d

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,8 +2016,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
20162016
case Type::Vector: {
20172017
const auto *VT = cast<VectorType>(T);
20182018
TypeInfo EltInfo = getTypeInfo(VT->getElementType());
2019-
Width = VT->isExtVectorBoolType() ? VT->getNumElements()
2020-
: EltInfo.Width * VT->getNumElements();
2019+
Width = (VT->isExtVectorBoolType() && !getLangOpts().HLSL)
2020+
? VT->getNumElements()
2021+
: EltInfo.Width * VT->getNumElements();
20212022
// Enforce at least byte size and alignment.
20222023
Width = std::max<unsigned>(8, Width);
20232024
Align = std::max<unsigned>(8, Width);

clang/lib/CodeGen/CGExprConstant.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,15 @@ llvm::Constant *ConstantEmitter::emitForMemory(CodeGenModule &CGM,
19841984
return Res;
19851985
}
19861986

1987+
// In HLSL bool vectors are stored in memory as a vector of i32
1988+
if (destType->isExtVectorBoolType() && CGM.getContext().getLangOpts().HLSL) {
1989+
llvm::Type *boolVecTy = CGM.getTypes().ConvertTypeForMem(destType);
1990+
llvm::Constant *Res = llvm::ConstantFoldCastOperand(
1991+
llvm::Instruction::ZExt, C, boolVecTy, CGM.getDataLayout());
1992+
assert(Res && "Constant folding must succeed");
1993+
return Res;
1994+
}
1995+
19871996
if (destType->isBitIntType()) {
19881997
ConstantAggregateBuilder Builder(CGM);
19891998
llvm::Type *LoadStoreTy = CGM.getTypes().convertTypeForLoadStore(destType);
Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,52 @@
11
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
22

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
714
// CHECK-NEXT: [[L:%.*]] = trunc <2 x i32> [[BoolVec:%.*]] to <2 x i1>
815
// CHECK-NEXT: [[VecExt:%.*]] = extractelement <2 x i1> [[L]], i32 0
916
// CHECK-NEXT: ret i1 [[VecExt]]
10-
bool fn() {
17+
bool fn1() {
1118
bool2 B = {true,true};
1219
return B[0];
1320
}
1421

15-
// CHECK-LABEL: fn2
22+
// CHECK-LABEL: define noundef <2 x i1> {{.*}}fn2{{.*}}
1623
// 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
1825
// CHECK-NEXT: [[StoreV:%.*]] = zext i1 {{.*}} to i32
1926
// CHECK-NEXT: store i32 [[StoreV]], ptr [[VAddr]], align 4
2027
// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[VAddr]], align 4
2128
// CHECK-NEXT: [[LoadV:%.*]] = trunc i32 [[L]] to i1
2229
// CHECK-NEXT: [[Vec:%.*]] = insertelement <2 x i1> poison, i1 [[LoadV]], i32 0
2330
// CHECK-NEXT: [[Vec1:%.*]] = insertelement <2 x i1> [[Vec]], i1 true, i32 1
2431
// 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
2734
// CHECK-NEXT: [[LoadV2:%.*]] = trunc <2 x i32> [[LoadBV]] to <2 x i1>
2835
// CHECK-NEXT: ret <2 x i1> [[LoadV2]]
2936
bool2 fn2(bool V) {
3037
bool2 A = {V,true};
3138
return A;
3239
}
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

Comments
 (0)