@@ -1376,10 +1376,37 @@ bool X86FastISel::X86SelectDivRem(const Instruction *I) {
1376
1376
// Generate the DIV/IDIV instruction.
1377
1377
BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL,
1378
1378
TII.get (OpEntry.OpDivRem )).addReg (Op1Reg);
1379
- // Copy output register into result register.
1380
- unsigned ResultReg = createResultReg (TypeEntry.RC );
1381
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL,
1382
- TII.get (Copy), ResultReg).addReg (OpEntry.DivRemResultReg );
1379
+ // For i8 remainder, we can't reference AH directly, as we'll end
1380
+ // up with bogus copies like %R9B = COPY %AH. Reference AX
1381
+ // instead to prevent AH references in a REX instruction.
1382
+ //
1383
+ // The current assumption of the fast register allocator is that isel
1384
+ // won't generate explicit references to the GPR8_NOREX registers. If
1385
+ // the allocator and/or the backend get enhanced to be more robust in
1386
+ // that regard, this can be, and should be, removed.
1387
+ unsigned ResultReg = 0 ;
1388
+ if ((I->getOpcode () == Instruction::SRem ||
1389
+ I->getOpcode () == Instruction::URem) &&
1390
+ OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit ()) {
1391
+ unsigned SourceSuperReg = createResultReg (&X86::GR16RegClass);
1392
+ unsigned ResultSuperReg = createResultReg (&X86::GR16RegClass);
1393
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL,
1394
+ TII.get (Copy), SourceSuperReg).addReg (X86::AX);
1395
+
1396
+ // Shift AX right by 8 bits instead of using AH.
1397
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, TII.get (X86::SHR16ri),
1398
+ ResultSuperReg).addReg (SourceSuperReg).addImm (8 );
1399
+
1400
+ // Now reference the 8-bit subreg of the result.
1401
+ ResultReg = FastEmitInst_extractsubreg (MVT::i8 , ResultSuperReg,
1402
+ /* Kill=*/ true , X86::sub_8bit);
1403
+ }
1404
+ // Copy the result out of the physreg if we haven't already.
1405
+ if (!ResultReg) {
1406
+ ResultReg = createResultReg (TypeEntry.RC );
1407
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, TII.get (Copy), ResultReg)
1408
+ .addReg (OpEntry.DivRemResultReg );
1409
+ }
1383
1410
UpdateValueMap (I, ResultReg);
1384
1411
1385
1412
return true ;
0 commit comments