@@ -498,6 +498,35 @@ RegRecord* LinearScan::getRegisterRecord(regNumber regNum)
498
498
return &physRegs[regNum];
499
499
}
500
500
501
+ //------------------------------------------------------------------------
502
+ // getAvailableGPRsForType: Returns available general-purpose registers for the given type,
503
+ // with platform-specific restrictions applied.
504
+ //
505
+ // Arguments:
506
+ // candidates - The candidate register mask to be filtered
507
+ // regType - The register type for which we need available registers
508
+ //
509
+ // Return Value:
510
+ // A filtered register mask with platform-specific restrictions applied.
511
+ // For AMD64: GC types and long types are restricted to low GPRs only.
512
+ // For other platforms: Returns the original candidates unchanged.
513
+ //
514
+ // Notes:
515
+ // On AMD64, we don't use extended GPRs (R16-R31) for GC types to ensure
516
+ // proper GC tracking and code generation compatibility.
517
+ //
518
+ SingleTypeRegSet LinearScan::getAvailableGPRsForType(SingleTypeRegSet candidates, var_types regType)
519
+ {
520
+ #ifdef TARGET_AMD64
521
+ if (varTypeIsGC(regType) || varTypeIsLong(regType))
522
+ {
523
+ // For AMD64, we don't use eGPR for GC types.
524
+ candidates &= (SingleTypeRegSet)RBM_LOWINT.getLow();
525
+ }
526
+ #endif // TARGET_AMD64
527
+ return candidates;
528
+ }
529
+
501
530
#ifdef DEBUG
502
531
503
532
//----------------------------------------------------------------------------
@@ -8694,6 +8723,9 @@ regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock,
8694
8723
}
8695
8724
#else // !TARGET_ARM
8696
8725
SingleTypeRegSet freeRegs = allRegs(type);
8726
+ // We call getTempRegForResolution() with only either TYP_INT or TYP_FLOAT.
8727
+ // We are being conservative with eGPR usage when type is TYP_INT since it could be a reference type.
8728
+ freeRegs = getAvailableGPRsForType(freeRegs, (type == TYP_INT) ? TYP_REF : type);
8697
8729
#endif // !TARGET_ARM
8698
8730
8699
8731
#ifdef DEBUG
@@ -13466,7 +13498,7 @@ SingleTypeRegSet LinearScan::RegisterSelection::select(Interval*
13466
13498
{
13467
13499
preferences = candidates;
13468
13500
}
13469
-
13501
+ candidates = linearScan->getAvailableGPRsForType(candidates, regType);
13470
13502
#ifdef DEBUG
13471
13503
candidates = linearScan->stressLimitRegs(refPosition, regType, candidates);
13472
13504
#endif
@@ -13934,7 +13966,7 @@ SingleTypeRegSet LinearScan::RegisterSelection::selectMinimal(
13934
13966
}
13935
13967
}
13936
13968
}
13937
-
13969
+ candidates = linearScan->getAvailableGPRsForType(candidates, regType);
13938
13970
#ifdef DEBUG
13939
13971
candidates = linearScan->stressLimitRegs(refPosition, regType, candidates);
13940
13972
#endif
0 commit comments