mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
X86 fast-isel: Avoid explicit AH subreg reference for [SU]Rem.
Explicit references to %AH for an i8 remainder instruction can lead to references to %AH in a REX prefixed instruction, which causes things to blow up. Do the same thing in FastISel as we do for DAG isel and instead shift %AX right by 8 bits and then extract the 8-bit subreg from that result. rdar://14203849 http://llvm.org/bugs/show_bug.cgi?id=16105 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185899 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
845e196a52
commit
cc64dc66e7
@ -1376,10 +1376,37 @@ bool X86FastISel::X86SelectDivRem(const Instruction *I) {
|
||||
// Generate the DIV/IDIV instruction.
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(OpEntry.OpDivRem)).addReg(Op1Reg);
|
||||
// Copy output register into result register.
|
||||
unsigned ResultReg = createResultReg(TypeEntry.RC);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(Copy), ResultReg).addReg(OpEntry.DivRemResultReg);
|
||||
// For i8 remainder, we can't reference AH directly, as we'll end
|
||||
// up with bogus copies like %R9B = COPY %AH. Reference AX
|
||||
// instead to prevent AH references in a REX instruction.
|
||||
//
|
||||
// The current assumption of the fast register allocator is that isel
|
||||
// won't generate explicit references to the GPR8_NOREX registers. If
|
||||
// the allocator and/or the backend get enhanced to be more robust in
|
||||
// that regard, this can be, and should be, removed.
|
||||
unsigned ResultReg = 0;
|
||||
if ((I->getOpcode() == Instruction::SRem ||
|
||||
I->getOpcode() == Instruction::URem) &&
|
||||
OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit()) {
|
||||
unsigned SourceSuperReg = createResultReg(&X86::GR16RegClass);
|
||||
unsigned ResultSuperReg = createResultReg(&X86::GR16RegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(Copy), SourceSuperReg).addReg(X86::AX);
|
||||
|
||||
// Shift AX right by 8 bits instead of using AH.
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::SHR16ri),
|
||||
ResultSuperReg).addReg(SourceSuperReg).addImm(8);
|
||||
|
||||
// Now reference the 8-bit subreg of the result.
|
||||
ResultReg = FastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
|
||||
/*Kill=*/true, X86::sub_8bit);
|
||||
}
|
||||
// Copy the result out of the physreg if we haven't already.
|
||||
if (!ResultReg) {
|
||||
ResultReg = createResultReg(TypeEntry.RC);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Copy), ResultReg)
|
||||
.addReg(OpEntry.DivRemResultReg);
|
||||
}
|
||||
UpdateValueMap(I, ResultReg);
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user