@@ -368,8 +368,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
368368 {
369369 if (isRMW)
370370 {
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 ) );
373373 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
374374
375375 HWIntrinsicImmOpHelper helper (this , intrin.op4 , node);
@@ -412,8 +412,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
412412 {
413413 if (isRMW)
414414 {
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 ) );
417417 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
418418 GetEmitter ()->emitIns_R_R_R_I (ins, emitSize, targetReg, op2Reg, op3Reg, 0 , opt);
419419 }
@@ -511,7 +511,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
511511 // If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the
512512 // destination using /Z.
513513
514- assert ((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg));
514+ assert ((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg) ||
515+ genIsSameLocalVar (intrinEmbMask.op1 , intrinEmbMask.op2 ));
515516 assert (intrin.op3 ->isContained () || !intrin.op1 ->IsTrueMask (node->GetSimdBaseType ()));
516517 GetEmitter ()->emitInsSve_R_R_R (INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt);
517518 }
@@ -765,14 +766,16 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
765766 switch (intrinEmbMask.id )
766767 {
767768 case NI_Sve_CreateBreakPropagateMask:
768- assert ((targetReg == embMaskOp2Reg) || (targetReg != embMaskOp1Reg));
769+ assert ((targetReg == embMaskOp2Reg) || (targetReg != embMaskOp1Reg) ||
770+ genIsSameLocalVar (intrinEmbMask.op1 , intrinEmbMask.op2 ));
769771 GetEmitter ()->emitIns_Mov (INS_sve_mov, emitSize, targetReg, embMaskOp2Reg,
770772 /* canSkip */ true );
771773 emitInsHelper (targetReg, maskReg, embMaskOp1Reg);
772774 break ;
773775
774776 case NI_Sve_AddSequentialAcross:
775- assert ((targetReg == op1Reg) || (targetReg != embMaskOp2Reg));
777+ assert ((targetReg == op1Reg) || (targetReg != embMaskOp2Reg) ||
778+ genIsSameLocalVar (intrinEmbMask.op1 , intrinEmbMask.op2 ));
776779 GetEmitter ()->emitIns_Mov (INS_fmov, GetEmitter ()->optGetSveElemsize (embOpt), targetReg,
777780 embMaskOp1Reg, /* canSkip */ true );
778781 emitInsHelper (targetReg, maskReg, embMaskOp2Reg);
@@ -1061,7 +1064,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
10611064 {
10621065 if (isRMW)
10631066 {
1064- assert ((targetReg == op2Reg) || (targetReg != op1Reg));
1067+ assert ((targetReg == op2Reg) || (targetReg != op1Reg) ||
1068+ genIsSameLocalVar (intrin.op1 , intrin.op2 ));
10651069 GetEmitter ()->emitIns_Mov (ins_Move_Extend (intrin.op2 ->TypeGet (), false ),
10661070 emitTypeSize (node), targetReg, op2Reg,
10671071 /* canSkip */ true );
@@ -1081,7 +1085,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
10811085 }
10821086 else if (isRMW)
10831087 {
1084- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
1088+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) ||
1089+ genIsSameLocalVar (intrin.op1 , intrin.op2 ));
10851090 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg,
10861091 /* canSkip */ true );
10871092 GetEmitter ()->emitIns_R_R (ins, emitSize, targetReg, op2Reg, opt);
@@ -1099,15 +1104,21 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
10991104 {
11001105 if (HWIntrinsicInfo::IsExplicitMaskedOperation (intrin.id ))
11011106 {
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 ));
11031111
11041112 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op2Reg,
11051113 /* canSkip */ true );
11061114 GetEmitter ()->emitIns_R_R_R (ins, emitSize, targetReg, op1Reg, op3Reg, opt);
11071115 }
11081116 else
11091117 {
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 ));
11111122
11121123 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg,
11131124 /* canSkip */ true );
@@ -1358,7 +1369,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
13581369 case NI_AdvSimd_InsertScalar:
13591370 {
13601371 assert (isRMW);
1361- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1372+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
13621373 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
13631374
13641375 HWIntrinsicImmOpHelper helper (this , intrin.op2 , node);
@@ -1375,7 +1386,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
13751386 case NI_AdvSimd_Arm64_InsertSelectedScalar:
13761387 {
13771388 assert (isRMW);
1378- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1389+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
13791390 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
13801391
13811392 const int resultIndex = (int )intrin.op2 ->AsIntCon ()->gtIconVal ;
@@ -1387,7 +1398,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
13871398 case NI_AdvSimd_LoadAndInsertScalar:
13881399 {
13891400 assert (isRMW);
1390- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1401+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
13911402 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
13921403
13931404 HWIntrinsicImmOpHelper helper (this , intrin.op2 , node);
@@ -1983,7 +1994,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
19831994 break ;
19841995 }
19851996
1986- assert ((targetReg == op1Reg) || (targetReg != op3Reg));
1997+ assert ((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar (intrin. op1 , intrin. op3 ) );
19871998 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
19881999 GetEmitter ()->emitIns_R_R_R (ins, emitSize, targetReg, op2Reg, op3Reg, opt);
19892000 break ;
@@ -2348,8 +2359,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
23482359 case NI_Sve_SaturatingIncrementBy8BitElementCount:
23492360 {
23502361 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 ) );
23532364 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
23542365
23552366 if (intrin.op2 ->IsCnsIntOrI () && intrin.op3 ->IsCnsIntOrI ())
@@ -2402,7 +2413,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
24022413 case NI_Sve_SaturatingIncrementByActiveElementCount:
24032414 {
24042415 // RMW semantics
2405- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2416+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
24062417 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
24072418
24082419 // Switch instruction if arg1 is unsigned.
@@ -2442,7 +2453,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
24422453 case NI_Sve_ExtractVector:
24432454 {
24442455 assert (isRMW);
2445- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2456+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
24462457 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg, /* canSkip */ true );
24472458
24482459 HWIntrinsicImmOpHelper helper (this , intrin.op3 , node);
@@ -2461,7 +2472,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
24612472 {
24622473 assert (isRMW);
24632474 assert (emitter::isFloatReg (op2Reg) == varTypeIsFloating (intrin.baseType ));
2464- assert ((targetReg == op1Reg) || (targetReg != op2Reg));
2475+ assert ((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar (intrin. op1 , intrin. op2 ) );
24652476 GetEmitter ()->emitIns_Mov (INS_mov, emitTypeSize (node), targetReg, op1Reg,
24662477 /* canSkip */ true );
24672478 GetEmitter ()->emitInsSve_R_R (ins, emitSize, targetReg, op2Reg, opt);
@@ -2487,7 +2498,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
24872498 {
24882499 assert (isRMW);
24892500 assert (HWIntrinsicInfo::IsExplicitMaskedOperation (intrin.id ));
2490- assert ((targetReg == op2Reg) || (targetReg != op1Reg));
2501+ assert ((targetReg == op2Reg) || (targetReg != op1Reg) || genIsSameLocalVar (intrin. op2 , intrin. op1 ) );
24912502 GetEmitter ()->emitIns_Mov (INS_sve_mov, emitTypeSize (node), targetReg, op2Reg, /* canSkip */ true );
24922503 GetEmitter ()->emitIns_R_R (ins, emitSize, targetReg, op1Reg, INS_OPTS_SCALABLE_B);
24932504 break ;
@@ -2559,8 +2570,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
25592570 {
25602571 assert (emitter::isFloatReg (targetReg));
25612572 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 ) );
25642575
25652576 GetEmitter ()->emitIns_Mov (INS_sve_mov, EA_SCALABLE, targetReg, op2Reg, /* canSkip */ true , opt);
25662577 GetEmitter ()->emitInsSve_R_R_R (ins, EA_SCALABLE, targetReg, op1Reg, op3Reg, opt,
0 commit comments