@@ -386,7 +386,8 @@ namespace {
386
386
// of the compare that produced them.
387
387
assert (VT->getElementType ()->getPrimitiveSizeInBits () == 32 ||
388
388
VT->getElementType ()->getPrimitiveSizeInBits () == 1 );
389
- assert (VT->getNumElements () == 4 );
389
+ assert (VT->getBitWidth () <= 128 );
390
+ assert (VT->getNumElements () <= 4 );
390
391
UsesSIMD = true ;
391
392
}
392
393
@@ -1074,18 +1075,23 @@ std::string JSWriter::getConstant(const Constant* CV, AsmCast sign) {
1074
1075
return " 0" ;
1075
1076
}
1076
1077
} else if (const ConstantDataVector *DV = dyn_cast<ConstantDataVector>(CV)) {
1077
- return getConstantVector (cast<VectorType>(CV->getType ())->getElementType (),
1078
- getConstant (DV->getElementAsConstant (0 )),
1079
- getConstant (DV->getElementAsConstant (1 )),
1080
- getConstant (DV->getElementAsConstant (2 )),
1081
- getConstant (DV->getElementAsConstant (3 )));
1078
+ unsigned NumElts = cast<VectorType>(DV->getType ())->getNumElements ();
1079
+ Type *EltTy = cast<VectorType>(DV->getType ())->getElementType ();
1080
+ Constant *Undef = UndefValue::get (EltTy);
1081
+ return getConstantVector (EltTy,
1082
+ getConstant (NumElts > 0 ? DV->getElementAsConstant (0 ) : Undef),
1083
+ getConstant (NumElts > 1 ? DV->getElementAsConstant (1 ) : Undef),
1084
+ getConstant (NumElts > 2 ? DV->getElementAsConstant (2 ) : Undef),
1085
+ getConstant (NumElts > 3 ? DV->getElementAsConstant (3 ) : Undef));
1082
1086
} else if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) {
1083
- assert (V->getNumOperands () == 4 );
1087
+ unsigned NumElts = cast<VectorType>(CV->getType ())->getNumElements ();
1088
+ Type *EltTy = cast<VectorType>(CV->getType ())->getElementType ();
1089
+ Constant *Undef = UndefValue::get (EltTy);
1084
1090
return getConstantVector (cast<VectorType>(V->getType ())->getElementType (),
1085
- getConstant (V->getOperand (0 )),
1086
- getConstant (V->getOperand (1 )),
1087
- getConstant (V->getOperand (2 )),
1088
- getConstant (V->getOperand (3 )));
1091
+ getConstant (NumElts > 0 ? V->getOperand (0 ) : Undef ),
1092
+ getConstant (NumElts > 1 ? V->getOperand (1 ) : Undef ),
1093
+ getConstant (NumElts > 2 ? V->getOperand (2 ) : Undef ),
1094
+ getConstant (NumElts > 3 ? V->getOperand (3 ) : Undef ));
1089
1095
} else if (const ConstantArray *CA = dyn_cast<const ConstantArray>(CV)) {
1090
1096
// handle things like [i8* bitcast (<{ i32, i32, i32 }>* @_ZTISt9bad_alloc to i8*)] which clang can emit for landingpads
1091
1097
assert (CA->getNumOperands () == 1 );
@@ -1300,20 +1306,22 @@ void JSWriter::generateShuffleVectorExpression(const ShuffleVectorInst *SVI, raw
1300
1306
// Check whether can generate SIMD.js swizzle or shuffle.
1301
1307
std::string A = getValueAsStr (SVI->getOperand (0 ));
1302
1308
std::string B = getValueAsStr (SVI->getOperand (1 ));
1303
- int Mask0 = SVI->getMaskValue (0 );
1304
- int Mask1 = SVI->getMaskValue (1 );
1305
- int Mask2 = SVI->getMaskValue (2 );
1306
- int Mask3 = SVI->getMaskValue (3 );
1309
+ int OpNumElements = cast<VectorType>(SVI->getOperand (0 )->getType ())->getNumElements ();
1310
+ int ResultNumElements = SVI->getType ()->getNumElements ();
1311
+ int Mask0 = ResultNumElements > 0 ? SVI->getMaskValue (0 ) : -1 ;
1312
+ int Mask1 = ResultNumElements > 1 ? SVI->getMaskValue (1 ) : -1 ;
1313
+ int Mask2 = ResultNumElements > 2 ? SVI->getMaskValue (2 ) : -1 ;
1314
+ int Mask3 = ResultNumElements > 3 ? SVI->getMaskValue (3 ) : -1 ;
1307
1315
bool swizzleA = false ;
1308
1316
bool swizzleB = false ;
1309
- if ((Mask0 < 4 ) && (Mask1 < 4 ) &&
1310
- (Mask2 < 4 ) && (Mask3 < 4 )) {
1317
+ if ((Mask0 < OpNumElements ) && (Mask1 < OpNumElements ) &&
1318
+ (Mask2 < OpNumElements ) && (Mask3 < OpNumElements )) {
1311
1319
swizzleA = true ;
1312
1320
}
1313
- if ((Mask0 < 0 || (Mask0 >= 4 && Mask0 < 8 )) &&
1314
- (Mask1 < 0 || (Mask1 >= 4 && Mask1 < 8 )) &&
1315
- (Mask2 < 0 || (Mask2 >= 4 && Mask2 < 8 )) &&
1316
- (Mask3 < 0 || (Mask3 >= 4 && Mask3 < 8 ))) {
1321
+ if ((Mask0 < 0 || (Mask0 >= OpNumElements && Mask0 < OpNumElements * 2 )) &&
1322
+ (Mask1 < 0 || (Mask1 >= OpNumElements && Mask1 < OpNumElements * 2 )) &&
1323
+ (Mask2 < 0 || (Mask2 >= OpNumElements && Mask2 < OpNumElements * 2 )) &&
1324
+ (Mask3 < 0 || (Mask3 >= OpNumElements && Mask3 < OpNumElements * 2 ))) {
1317
1325
swizzleB = true ;
1318
1326
}
1319
1327
assert (!(swizzleA && swizzleB));
@@ -1324,18 +1332,22 @@ void JSWriter::generateShuffleVectorExpression(const ShuffleVectorInst *SVI, raw
1324
1332
} else {
1325
1333
Code << " SIMD_float32x4_swizzle(" << T;
1326
1334
}
1327
- for (unsigned int i = 0 ; i < 4 ; i++) {
1335
+ int i = 0 ;
1336
+ for (; i < ResultNumElements; ++i) {
1328
1337
Code << " , " ;
1329
1338
int Mask = SVI->getMaskValue (i);
1330
1339
if (Mask < 0 ) {
1331
1340
Code << 0 ;
1332
- } else if (Mask < 4 ) {
1341
+ } else if (Mask < OpNumElements ) {
1333
1342
Code << Mask;
1334
1343
} else {
1335
- assert (Mask < 8 );
1336
- Code << (Mask-4 );
1344
+ assert (Mask < OpNumElements * 2 );
1345
+ Code << (Mask-OpNumElements );
1337
1346
}
1338
1347
}
1348
+ for (; i < 4 ; ++i) {
1349
+ Code << " , 0" ;
1350
+ }
1339
1351
Code << " )" ;
1340
1352
return ;
1341
1353
}
@@ -1354,7 +1366,10 @@ void JSWriter::generateShuffleVectorExpression(const ShuffleVectorInst *SVI, raw
1354
1366
for (unsigned int i = 0 ; i < Indices.size (); ++i) {
1355
1367
if (i != 0 )
1356
1368
Code << " , " ;
1357
- Code << Indices[i];
1369
+ int Mask = Indices[i];
1370
+ if (Mask >= OpNumElements)
1371
+ Mask = Mask - OpNumElements + 4 ;
1372
+ Code << Mask;
1358
1373
}
1359
1374
1360
1375
Code << " )" ;
@@ -1626,11 +1641,15 @@ bool JSWriter::generateSIMDExpression(const User *I, raw_string_ostream& Code) {
1626
1641
const LoadInst *LI = cast<LoadInst>(I);
1627
1642
const Value *P = LI->getPointerOperand ();
1628
1643
std::string PS = getValueAsStr (P);
1644
+
1645
+ // Determine if this is a partial store.
1646
+ std::string Part = (std::string[]) { " X" , " XY" , " XYZ" , " " }[VT->getNumElements () - 1 ];
1647
+
1629
1648
Code << getAssignIfNeeded (I);
1630
1649
if (VT->getElementType ()->isIntegerTy ()) {
1631
- Code << " SIMD_int32x4_load(HEAPU8, " << PS << " )" ;
1650
+ Code << " SIMD_int32x4_load" << Part << " (HEAPU8, " << PS << " )" ;
1632
1651
} else {
1633
- Code << " SIMD_float32x4_load(HEAPU8, " << PS << " )" ;
1652
+ Code << " SIMD_float32x4_load" << Part << " (HEAPU8, " << PS << " )" ;
1634
1653
}
1635
1654
break ;
1636
1655
}
@@ -1666,10 +1685,14 @@ bool JSWriter::generateSIMDExpression(const User *I, raw_string_ostream& Code) {
1666
1685
std::string PS = getOpName (P);
1667
1686
std::string VS = getValueAsStr (SI->getValueOperand ());
1668
1687
Code << getAdHocAssign (PS, P->getType ()) << getValueAsStr (P) << ' ;' ;
1688
+
1689
+ // Determine if this is a partial store.
1690
+ std::string Part = (std::string[]) { " X" , " XY" , " XYZ" , " " }[VT->getNumElements () - 1 ];
1691
+
1669
1692
if (VT->getElementType ()->isIntegerTy ()) {
1670
- Code << " SIMD_int32x4_store(HEAPU8, " << PS << " , " << VS << " )" ;
1693
+ Code << " SIMD_int32x4_store" << Part << " (HEAPU8, " << PS << " , " << VS << " )" ;
1671
1694
} else {
1672
- Code << " SIMD_float32x4_store(HEAPU8, " << PS << " , " << VS << " )" ;
1695
+ Code << " SIMD_float32x4_store" << Part << " (HEAPU8, " << PS << " , " << VS << " )" ;
1673
1696
}
1674
1697
return true ;
1675
1698
} else if (Operator::getOpcode (I) == Instruction::ExtractElement) {
0 commit comments