@@ -1985,7 +1985,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
1985
1985
1986
1986
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
1987
1987
// Boolean vectors use `iN` as storage type.
1988
- if (ClangVecTy->isExtVectorBoolType( )) {
1988
+ if (ClangVecTy->isPackedVectorBoolType(getContext() )) {
1989
1989
llvm::Type *ValTy = ConvertType(Ty);
1990
1990
unsigned ValNumElems =
1991
1991
cast<llvm::FixedVectorType>(ValTy)->getNumElements();
@@ -2064,6 +2064,10 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
2064
2064
2065
2065
if (Ty->isExtVectorBoolType()) {
2066
2066
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
2067
+ if (StoreTy->isVectorTy() && StoreTy->getScalarSizeInBits() >
2068
+ Value->getType()->getScalarSizeInBits())
2069
+ return Builder.CreateZExt(Value, StoreTy);
2070
+
2067
2071
// Expand to the memory bit width.
2068
2072
unsigned MemNumElems = StoreTy->getPrimitiveSizeInBits();
2069
2073
// <N x i1> --> <P x i1>.
@@ -2079,8 +2083,9 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
2079
2083
/// by convertTypeForLoadStore) to its primary IR type (as returned
2080
2084
/// by ConvertType).
2081
2085
llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
2082
- if (Ty->isExtVectorBoolType( )) {
2086
+ if (Ty->isPackedVectorBoolType(getContext() )) {
2083
2087
const auto *RawIntTy = Value->getType();
2088
+
2084
2089
// Bitcast iP --> <P x i1>.
2085
2090
auto *PaddedVecTy = llvm::FixedVectorType::get(
2086
2091
Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
@@ -2091,10 +2096,10 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
2091
2096
return emitBoolVecConversion(V, ValNumElems, "extractvec");
2092
2097
}
2093
2098
2094
- if (hasBooleanRepresentation(Ty) || Ty->isBitIntType()) {
2095
- llvm::Type *ResTy = ConvertType(Ty);
2099
+ llvm::Type *ResTy = ConvertType(Ty);
2100
+ if (hasBooleanRepresentation(Ty) || Ty->isBitIntType() ||
2101
+ Ty->isExtVectorBoolType())
2096
2102
return Builder.CreateTrunc(Value, ResTy, "loadedv");
2097
- }
2098
2103
2099
2104
return Value;
2100
2105
}
@@ -2152,7 +2157,8 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
2152
2157
if (auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2153
2158
auto *NewVecTy =
2154
2159
CGM.getABIInfo().getOptimalVectorMemoryType(VecTy, getLangOpts());
2155
- if (!ClangVecTy->isExtVectorBoolType() && VecTy != NewVecTy) {
2160
+ if (!ClangVecTy->isPackedVectorBoolType(getContext()) &&
2161
+ VecTy != NewVecTy) {
2156
2162
SmallVector<int, 16> Mask(NewVecTy->getNumElements(), -1);
2157
2163
std::iota(Mask.begin(), Mask.begin() + VecTy->getNumElements(), 0);
2158
2164
Value = Builder.CreateShuffleVector(Value, Mask, "extractVec");
@@ -2343,7 +2349,15 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
2343
2349
if (!ExprVT) {
2344
2350
unsigned InIdx = getAccessedFieldNo(0, Elts);
2345
2351
llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
2346
- return RValue::get(Builder.CreateExtractElement(Vec, Elt));
2352
+
2353
+ llvm::Value *Element = Builder.CreateExtractElement(Vec, Elt);
2354
+
2355
+ llvm::Type *LVTy = ConvertType(LV.getType());
2356
+ if (Element->getType()->getPrimitiveSizeInBits() >
2357
+ LVTy->getPrimitiveSizeInBits())
2358
+ Element = Builder.CreateTrunc(Element, LVTy);
2359
+
2360
+ return RValue::get(Element);
2347
2361
}
2348
2362
2349
2363
// Always use shuffle vector to try to retain the original program structure
@@ -2354,6 +2368,10 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
2354
2368
Mask.push_back(getAccessedFieldNo(i, Elts));
2355
2369
2356
2370
Vec = Builder.CreateShuffleVector(Vec, Mask);
2371
+
2372
+ if (LV.getType()->isExtVectorBoolType())
2373
+ Vec = Builder.CreateTrunc(Vec, ConvertType(LV.getType()), "truncv");
2374
+
2357
2375
return RValue::get(Vec);
2358
2376
}
2359
2377
@@ -2407,26 +2425,35 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
2407
2425
// Read/modify/write the vector, inserting the new element.
2408
2426
llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddress(),
2409
2427
Dst.isVolatileQualified());
2428
+ llvm::Type *VecTy = Vec->getType();
2429
+ llvm::Value *SrcVal = Src.getScalarVal();
2430
+
2431
+ if (SrcVal->getType()->getPrimitiveSizeInBits() <
2432
+ VecTy->getScalarSizeInBits())
2433
+ SrcVal = Builder.CreateZExt(SrcVal, VecTy->getScalarType());
2434
+
2410
2435
auto *IRStoreTy = dyn_cast<llvm::IntegerType>(Vec->getType());
2411
2436
if (IRStoreTy) {
2412
2437
auto *IRVecTy = llvm::FixedVectorType::get(
2413
2438
Builder.getInt1Ty(), IRStoreTy->getPrimitiveSizeInBits());
2414
2439
Vec = Builder.CreateBitCast(Vec, IRVecTy);
2415
2440
// iN --> <N x i1>.
2416
2441
}
2417
- llvm::Value *SrcVal = Src.getScalarVal();
2442
+
2418
2443
// Allow inserting `<1 x T>` into an `<N x T>`. It can happen with scalar
2419
2444
// types which are mapped to vector LLVM IR types (e.g. for implementing
2420
2445
// an ABI).
2421
2446
if (auto *EltTy = dyn_cast<llvm::FixedVectorType>(SrcVal->getType());
2422
2447
EltTy && EltTy->getNumElements() == 1)
2423
2448
SrcVal = Builder.CreateBitCast(SrcVal, EltTy->getElementType());
2449
+
2424
2450
Vec = Builder.CreateInsertElement(Vec, SrcVal, Dst.getVectorIdx(),
2425
2451
"vecins");
2426
2452
if (IRStoreTy) {
2427
2453
// <N x i1> --> <iN>.
2428
2454
Vec = Builder.CreateBitCast(Vec, IRStoreTy);
2429
2455
}
2456
+
2430
2457
Builder.CreateStore(Vec, Dst.getVectorAddress(),
2431
2458
Dst.isVolatileQualified());
2432
2459
return;
@@ -2623,14 +2650,12 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
2623
2650
// This access turns into a read/modify/write of the vector. Load the input
2624
2651
// value now.
2625
2652
llvm::Value *Vec = Builder.CreateLoad(DstAddr, Dst.isVolatileQualified());
2653
+ llvm::Type *VecTy = Vec->getType();
2626
2654
const llvm::Constant *Elts = Dst.getExtVectorElts();
2627
2655
2628
- llvm::Value *SrcVal = Src.getScalarVal();
2629
-
2630
2656
if (const VectorType *VTy = Dst.getType()->getAs<VectorType>()) {
2631
2657
unsigned NumSrcElts = VTy->getNumElements();
2632
- unsigned NumDstElts =
2633
- cast<llvm::FixedVectorType>(Vec->getType())->getNumElements();
2658
+ unsigned NumDstElts = cast<llvm::FixedVectorType>(VecTy)->getNumElements();
2634
2659
if (NumDstElts == NumSrcElts) {
2635
2660
// Use shuffle vector is the src and destination are the same number of
2636
2661
// elements and restore the vector mask since it is on the side it will be
@@ -2639,6 +2664,11 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
2639
2664
for (unsigned i = 0; i != NumSrcElts; ++i)
2640
2665
Mask[getAccessedFieldNo(i, Elts)] = i;
2641
2666
2667
+ llvm::Value *SrcVal = Src.getScalarVal();
2668
+ if (VecTy->getScalarSizeInBits() >
2669
+ SrcVal->getType()->getScalarSizeInBits())
2670
+ SrcVal = Builder.CreateZExt(SrcVal, VecTy);
2671
+
2642
2672
Vec = Builder.CreateShuffleVector(SrcVal, Mask);
2643
2673
} else if (NumDstElts > NumSrcElts) {
2644
2674
// Extended the source vector to the same length and then shuffle it
@@ -2649,7 +2679,8 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
2649
2679
for (unsigned i = 0; i != NumSrcElts; ++i)
2650
2680
ExtMask.push_back(i);
2651
2681
ExtMask.resize(NumDstElts, -1);
2652
- llvm::Value *ExtSrcVal = Builder.CreateShuffleVector(SrcVal, ExtMask);
2682
+ llvm::Value *ExtSrcVal =
2683
+ Builder.CreateShuffleVector(Src.getScalarVal(), ExtMask);
2653
2684
// build identity
2654
2685
SmallVector<int, 4> Mask;
2655
2686
for (unsigned i = 0; i != NumDstElts; ++i)
@@ -2674,6 +2705,11 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
2674
2705
// be updating one element.
2675
2706
unsigned InIdx = getAccessedFieldNo(0, Elts);
2676
2707
llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
2708
+
2709
+ llvm::Value *SrcVal = Src.getScalarVal();
2710
+ if (VecTy->getScalarSizeInBits() > SrcVal->getType()->getScalarSizeInBits())
2711
+ SrcVal = Builder.CreateZExt(SrcVal, VecTy->getScalarType());
2712
+
2677
2713
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt);
2678
2714
}
2679
2715
@@ -4701,9 +4737,13 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
4701
4737
4702
4738
// Store the vector to memory (because LValue wants an address).
4703
4739
Address VecMem = CreateMemTemp(E->getBase()->getType());
4740
+ // need to zero extend an hlsl boolean vector to store it back to memory
4741
+ QualType Ty = E->getBase()->getType();
4742
+ llvm::Type *LTy = convertTypeForLoadStore(Ty, Vec->getType());
4743
+ if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
4744
+ Vec = Builder.CreateZExt(Vec, LTy);
4704
4745
Builder.CreateStore(Vec, VecMem);
4705
- Base = MakeAddrLValue(VecMem, E->getBase()->getType(),
4706
- AlignmentSource::Decl);
4746
+ Base = MakeAddrLValue(VecMem, Ty, AlignmentSource::Decl);
4707
4747
}
4708
4748
4709
4749
QualType type =
0 commit comments