@@ -374,10 +374,11 @@ class GenXKernelBuilder final {
374
374
// The default float control from kernel attribute. Each subroutine may
375
375
// overrride this control mask, but it should revert back to the default float
376
376
// control mask before exiting from the subroutine.
377
- uint32_t DefaultFloatControl = 0 ;
377
+ uint32_t FloatControlKernel = 0 ;
378
+ uint32_t FloatControlMask = 0 ;
378
379
379
-
380
- uint32_t CRMask = 0 ;
380
+ // The hardware-initialization value for the float control register.
381
+ static constexpr uint32_t FloatControlDefault = 0x0 ;
381
382
382
383
// normally false, set to true if there is any SIMD CF in the func or this is
383
384
// (indirectly) called inside any SIMD CF.
@@ -1096,11 +1097,15 @@ bool GenXKernelBuilder::run() {
1096
1097
StackSurf = Subtarget->stackSurface ();
1097
1098
1098
1099
using namespace visa ;
1099
- CRMask = CRBits::RoundingBitMask | CRBits::DoublePrecisionDenorm |
1100
- CRBits::SinglePrecisionDenorm | CRBits::HalfPrecisionDenorm;
1100
+ FloatControlMask = CRBits::DoublePrecisionDenorm |
1101
+ CRBits::SinglePrecisionDenorm |
1102
+ CRBits::HalfPrecisionDenorm | CRBits::RoundingBitMask;
1103
+ FloatControlKernel = CRBits::RTNE;
1101
1104
1105
+ // If the subtarget supports systolic denorm control, retain denormals for the
1106
+ // systolic.
1102
1107
if (Subtarget->hasSystolicDenormControl ())
1103
- CRMask |= CRBits::SystolicDenorm;
1108
+ FloatControlKernel |= CRBits::SystolicDenorm;
1104
1109
1105
1110
StackCallExecSize =
1106
1111
getExecSizeFromValue (BackendConfig->getInteropSubgroupSize ());
@@ -1294,27 +1299,32 @@ void GenXKernelBuilder::buildInstructions() {
1294
1299
beginFunctionLight (Func);
1295
1300
1296
1301
// If a float control is specified, emit code to make that happen.
1297
- // Float control contains rounding mode, denorm behaviour and single
1298
- // precision float mode (ALT or IEEE) Relevant bits are already set as
1299
- // defined for VISA control reg in header definition on enums
1302
+ // Float control contains rounding mode and denorm behaviour. Relevant bits
1303
+ // are already set as defined for VISA control reg in header definition on
1304
+ // enums.
1305
+ uint32_t FloatControl = FloatControlKernel;
1306
+
1300
1307
if (Func->hasFnAttribute (genx::FunctionMD::CMFloatControl)) {
1301
- uint32_t FloatControl = 0 ;
1302
1308
Func->getFnAttribute (genx::FunctionMD::CMFloatControl)
1303
1309
.getValueAsString ()
1304
1310
.getAsInteger (0 , FloatControl);
1305
1311
1306
- // Clear current float control bits to known zero state
1307
- buildControlRegUpdate (CRMask, true );
1308
-
1309
1312
// Set rounding mode to required state if that isn't zero
1310
- FloatControl &= CRMask;
1311
- if (FloatControl) {
1312
- if (FG->getHead () == Func)
1313
- DefaultFloatControl = FloatControl;
1314
- buildControlRegUpdate (FloatControl, false );
1313
+ FloatControl &= FloatControlMask;
1314
+ FloatControl |= FloatControlKernel & ~FloatControlMask;
1315
+ if (FloatControl != (FloatControlKernel & FloatControlMask) &&
1316
+ vc::isKernel (Func)) {
1317
+ FloatControlKernel &= ~FloatControlMask;
1318
+ FloatControlKernel |= FloatControl;
1315
1319
}
1316
1320
}
1317
1321
1322
+ if ((vc::isKernel (Func) && FloatControlKernel != 0 ) ||
1323
+ FloatControl != (FloatControlKernel & FloatControlMask)) {
1324
+ buildControlRegUpdate (FloatControlMask, true );
1325
+ buildControlRegUpdate (FloatControl, false );
1326
+ }
1327
+
1318
1328
// Only output a label for the initial basic block if it is used from
1319
1329
// somewhere else.
1320
1330
bool NeedsLabel = !Func->front ().use_empty ();
@@ -5475,11 +5485,11 @@ void GenXKernelBuilder::buildRet(ReturnInst *RI) {
5475
5485
F->getFnAttribute (genx::FunctionMD::CMFloatControl)
5476
5486
.getValueAsString ()
5477
5487
.getAsInteger (0 , FloatControl);
5478
- FloatControl &= CRMask ;
5479
- if (FloatControl != DefaultFloatControl ) {
5480
- buildControlRegUpdate (CRMask , true );
5481
- if (DefaultFloatControl )
5482
- buildControlRegUpdate (DefaultFloatControl , false );
5488
+ FloatControl &= FloatControlMask ;
5489
+ if (FloatControl != (FloatControlKernel & FloatControlMask) ) {
5490
+ buildControlRegUpdate (FloatControlMask , true );
5491
+ if (FloatControlKernel & FloatControlMask )
5492
+ buildControlRegUpdate (FloatControlKernel , false );
5483
5493
}
5484
5494
if (vc::requiresStackCall (Func)) {
5485
5495
appendVISACFFunctionRetInst (nullptr , vISA_EMASK_M1, StackCallExecSize);
0 commit comments