@@ -368,8 +368,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
368
368
{
369
369
if (isRMW)
370
370
{
371
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
372
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
371
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
372
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
373
373
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
374
374
375
375
HWIntrinsicImmOpHelper helper (this , intrin.op4 , node);
@@ -412,8 +412,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
412
412
{
413
413
if (isRMW)
414
414
{
415
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
416
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
415
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
416
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
417
417
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
418
418
GetEmitter ()->emitIns_R_R_R_I (ins, emitSize, targetReg, op2Reg, op3Reg, 0 , opt);
419
419
}
@@ -511,7 +511,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
511
511
// If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the
512
512
// destination using /Z.
513
513
514
- assert ((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg));
514
+ assert ((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg) ||
515
+ genIsSameLocalVar (intrinEmbMask.op1 , intrinEmbMask.op2 ));
515
516
assert (intrin.op3 ->isContained () || !intrin.op1 ->IsTrueMask (node->GetSimdBaseType ()));
516
517
GetEmitter ()->emitInsSve_R_R_R (INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt);
517
518
}
@@ -765,14 +766,16 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
765
766
switch (intrinEmbMask.id )
766
767
{
767
768
case NI_Sve_CreateBreakPropagateMask:
768
- assert ((targetReg == embMaskOp2Reg) || (targetReg != embMaskOp1Reg));
769
+ assert ((targetReg == embMaskOp2Reg) || (targetReg != embMaskOp1Reg) ||
770
+ genIsSameLocalVar (intrinEmbMask.op1 , intrinEmbMask.op2 ));
769
771
GetEmitter ()->emitIns_Mov (INS_sve_mov, emitSize, targetReg, embMaskOp2Reg,
770
772
/* canSkip */ true );
771
773
emitInsHelper (targetReg, maskReg, embMaskOp1Reg);
772
774
break ;
773
775
774
776
case NI_Sve_AddSequentialAcross:
775
- assert ((targetReg == op1Reg) || (targetReg != embMaskOp2Reg));
777
+ assert ((targetReg == op1Reg) || (targetReg != embMaskOp2Reg) ||
778
+ genIsSameLocalVar (intrinEmbMask.op1 , intrinEmbMask.op2 ));
776
779
GetEmitter ()->emitIns_Mov (INS_fmov, GetEmitter ()->optGetSveElemsize (embOpt), targetReg,
777
780
embMaskOp1Reg, /* canSkip */ true );
778
781
emitInsHelper (targetReg, maskReg, embMaskOp2Reg);
@@ -1061,7 +1064,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1061
1064
{
1062
1065
if (isRMW)
1063
1066
{
1064
- assert ((targetReg == op2Reg) || (targetReg != op1Reg));
1067
+ assert ((targetReg == op2Reg) || (targetReg != op1Reg) ||
1068
+ genIsSameLocalVar (intrin.op1 , intrin.op2 ));
1065
1069
GetEmitter ()->emitIns_Mov (ins_Move_Extend (intrin.op2 ->TypeGet (), false ),
1066
1070
emitTypeSize (node), targetReg, op2Reg,
1067
1071
/* canSkip */ true );
@@ -1081,7 +1085,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1081
1085
}
1082
1086
else if (isRMW)
1083
1087
{
1084
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
1088
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) ||
1089
+ genIsSameLocalVar (intrin.op1 , intrin.op2 ));
1085
1090
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg,
1086
1091
/* canSkip */ true );
1087
1092
GetEmitter ()->emitIns_R_R (ins, emitSize, targetReg, op2Reg, opt);
@@ -1099,15 +1104,21 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1099
1104
{
1100
1105
if (HWIntrinsicInfo::IsExplicitMaskedOperation (intrin.id ))
1101
1106
{
1102
- assert ((targetReg == op2Reg) || ((targetReg != op1Reg) && (targetReg != op3Reg)));
1107
+ assert ((targetReg == op2Reg) || (targetReg != op1Reg) ||
1108
+ genIsSameLocalVar (intrin.op2 , intrin.op1 ));
1109
+ assert ((targetReg == op2Reg) || (targetReg != op3Reg) ||
1110
+ genIsSameLocalVar (intrin.op2 , intrin.op3 ));
1103
1111
1104
1112
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op2Reg,
1105
1113
/* canSkip */ true );
1106
1114
GetEmitter ()->emitIns_R_R_R (ins, emitSize, targetReg, op1Reg, op3Reg, opt);
1107
1115
}
1108
1116
else
1109
1117
{
1110
- assert ((targetReg == op1Reg) || ((targetReg != op2Reg) && (targetReg != op3Reg)));
1118
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) ||
1119
+ genIsSameLocalVar (intrin.op1 , intrin.op2 ));
1120
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) ||
1121
+ genIsSameLocalVar (intrin.op1 , intrin.op3 ));
1111
1122
1112
1123
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg,
1113
1124
/* canSkip */ true );
@@ -1358,7 +1369,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1358
1369
case NI_AdvSimd_InsertScalar:
1359
1370
{
1360
1371
assert (isRMW);
1361
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1372
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
1362
1373
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
1363
1374
1364
1375
HWIntrinsicImmOpHelper helper (this , intrin.op2 , node);
@@ -1375,7 +1386,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1375
1386
case NI_AdvSimd_Arm64_InsertSelectedScalar:
1376
1387
{
1377
1388
assert (isRMW);
1378
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1389
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
1379
1390
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
1380
1391
1381
1392
const int resultIndex = (int )intrin.op2 ->AsIntCon ()->gtIconVal ;
@@ -1387,7 +1398,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1387
1398
case NI_AdvSimd_LoadAndInsertScalar:
1388
1399
{
1389
1400
assert (isRMW);
1390
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1401
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
1391
1402
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
1392
1403
1393
1404
HWIntrinsicImmOpHelper helper (this , intrin.op2 , node);
@@ -1983,7 +1994,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
1983
1994
break ;
1984
1995
}
1985
1996
1986
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1997
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
1987
1998
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
1988
1999
GetEmitter ()->emitIns_R_R_R (ins, emitSize, targetReg, op2Reg, op3Reg, opt);
1989
2000
break ;
@@ -2348,8 +2359,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
2348
2359
case NI_Sve_SaturatingIncrementBy8BitElementCount:
2349
2360
{
2350
2361
assert (isRMW);
2351
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2352
- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
2362
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
2363
+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
2353
2364
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
2354
2365
2355
2366
if (intrin.op2 ->IsCnsIntOrI () && intrin.op3 ->IsCnsIntOrI ())
@@ -2402,7 +2413,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
2402
2413
case NI_Sve_SaturatingIncrementByActiveElementCount:
2403
2414
{
2404
2415
// RMW semantics
2405
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2416
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
2406
2417
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
2407
2418
2408
2419
// Switch instruction if arg1 is unsigned.
@@ -2442,7 +2453,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
2442
2453
case NI_Sve_ExtractVector:
2443
2454
{
2444
2455
assert (isRMW);
2445
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2456
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
2446
2457
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
2447
2458
2448
2459
HWIntrinsicImmOpHelper helper (this , intrin.op3 , node);
@@ -2461,7 +2472,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
2461
2472
{
2462
2473
assert (isRMW);
2463
2474
assert (emitter::isFloatReg (op2Reg) == varTypeIsFloating (intrin.baseType ));
2464
- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2475
+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
2465
2476
GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg,
2466
2477
/* canSkip */ true );
2467
2478
GetEmitter ()->emitInsSve_R_R (ins, emitSize, targetReg, op2Reg, opt);
@@ -2487,7 +2498,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
2487
2498
{
2488
2499
assert (isRMW);
2489
2500
assert (HWIntrinsicInfo::IsExplicitMaskedOperation (intrin.id ));
2490
- assert ((targetReg == op2Reg) || (targetReg != op1Reg));
2501
+ assert ((targetReg == op2Reg) || (targetReg != op1Reg) || genIsSameLocalVar (intrin. op2 , intrin. op1 ) );
2491
2502
GetEmitter ()->emitIns_Mov (INS_sve_mov, emitTypeSize (node), targetReg, op2Reg, /* canSkip */ true );
2492
2503
GetEmitter ()->emitIns_R_R (ins, emitSize, targetReg, op1Reg, INS_OPTS_SCALABLE_B);
2493
2504
break ;
@@ -2559,8 +2570,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
2559
2570
{
2560
2571
assert (emitter::isFloatReg (targetReg));
2561
2572
assert (varTypeIsFloating (node->gtType ) || varTypeIsSIMD (node->gtType ));
2562
- assert ((targetReg == op2Reg) || (targetReg != op1Reg));
2563
- assert ((targetReg == op2Reg) || (targetReg != op3Reg));
2573
+ assert ((targetReg == op2Reg) || (targetReg != op1Reg) || genIsSameLocalVar (intrin. op2 , intrin. op1 ) );
2574
+ assert ((targetReg == op2Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op2 , intrin. op3 ) );
2564
2575
2565
2576
GetEmitter ()->emitIns_Mov (INS_sve_mov, EA_SCALABLE, targetReg, op2Reg, /* canSkip */ true , opt);
2566
2577
GetEmitter ()->emitInsSve_R_R_R (ins, EA_SCALABLE, targetReg, op1Reg, op3Reg, opt,
0 commit comments