@@ -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