diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -3500,8 +3500,8 @@ Operands[0] = X86Operand::CreateToken(Name, NameLoc); } // Select the correct equivalent 16-/32-bit source register. - unsigned Reg = - getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32); + MCRegister Reg = + getX86SubSuperRegister(Op1.getReg(), is16BitMode() ? 16 : 32); Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc); } } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h @@ -135,16 +135,13 @@ std::unique_ptr createX86WinCOFFObjectWriter(bool Is64Bit); -/// Returns the sub or super register of a specific X86 register. -/// e.g. getX86SubSuperRegister(X86::EAX, 16) returns X86::AX. -/// Aborts on error. -MCRegister getX86SubSuperRegister(MCRegister, unsigned, bool High=false); - -/// Returns the sub or super register of a specific X86 register. -/// Like getX86SubSuperRegister() but returns 0 on error. -MCRegister getX86SubSuperRegisterOrZero(MCRegister, unsigned, - bool High = false); - +/// \param Reg speicifed register. +/// \param Size the bit size of returned register. +/// \param High requires the high register. +/// +/// \returns the sub or super register of a specific X86 register. +MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, + bool High = false); } // End llvm namespace diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -742,22 +742,14 @@ createX86_64AsmBackend); } -MCRegister llvm::getX86SubSuperRegisterOrZero(MCRegister Reg, unsigned Size, - bool High) { +MCRegister llvm::getX86SubSuperRegister(MCRegister Reg, unsigned Size, + bool High) { switch (Size) { default: return X86::NoRegister; case 8: if (High) { switch (Reg.id()) { - default: return getX86SubSuperRegisterOrZero(Reg, 64); - case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI: - return X86::SI; - case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI: - return X86::DI; - case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP: - return X86::BP; - case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP: - return X86::SP; + default: return X86::NoRegister; case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX: return X86::AH; case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX: @@ -914,11 +906,3 @@ } } } - -MCRegister llvm::getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High) { - MCRegister Res = getX86SubSuperRegisterOrZero(Reg, Size, High); - assert(Res != X86::NoRegister && "Unexpected register or VT"); - return Res; -} - - diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -546,6 +546,8 @@ break; case 'h': // Print QImode high register Reg = getX86SubSuperRegister(Reg, 8, true); + if (Reg == X86::NoRegister) + return true; break; case 'w': // Print HImode register Reg = getX86SubSuperRegister(Reg, 16); diff --git a/llvm/lib/Target/X86/X86FixupBWInsts.cpp b/llvm/lib/Target/X86/X86FixupBWInsts.cpp --- a/llvm/lib/Target/X86/X86FixupBWInsts.cpp +++ b/llvm/lib/Target/X86/X86FixupBWInsts.cpp @@ -213,9 +213,9 @@ // If the original destination register was the low 8-bit subregister and // we also need to check the 16-bit subregister and the high 8-bit // subregister. + MCRegister HighReg = getX86SubSuperRegister(SuperDestReg, 8, /*High=*/true); if (!LiveRegs.contains(getX86SubSuperRegister(OrigDestReg, 16)) && - !LiveRegs.contains(getX86SubSuperRegister(SuperDestReg, 8, - /*High=*/true))) + (HighReg == X86::NoRegister || !LiveRegs.contains(HighReg))) return true; // Otherwise, we have a little more checking to do. } diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -528,7 +528,7 @@ BitVector GPRsToZero(TRI->getNumRegs()); for (MCRegister Reg : RegsToZero.set_bits()) if (TRI->isGeneralPurposeRegister(MF, Reg)) { - GPRsToZero.set(getX86SubSuperRegisterOrZero(Reg, 32)); + GPRsToZero.set(getX86SubSuperRegister(Reg, 32)); RegsToZero.reset(Reg); } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -57576,8 +57576,8 @@ if (isGRClass(*Class)) { unsigned Size = VT.getSizeInBits(); if (Size == 1) Size = 8; - Register DestReg = getX86SubSuperRegisterOrZero(Res.first, Size); - if (DestReg > 0) { + Register DestReg = getX86SubSuperRegister(Res.first, Size); + if (DestReg != X86::NoRegister) { bool is64Bit = Subtarget.is64Bit(); const TargetRegisterClass *RC = Size == 8 ? (is64Bit ? &X86::GR8RegClass : &X86::GR8_NOREXRegClass) diff --git a/llvm/test/CodeGen/X86/asm-modifier-error.ll b/llvm/test/CodeGen/X86/asm-modifier-error.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/asm-modifier-error.ll @@ -0,0 +1,9 @@ +; RUN: not llc < %s -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s + +; CHECK: error: invalid operand in inline asm: 'mov %ah, ${0:h}' +define void @test1() { +entry: + %0 = tail call i8 asm sideeffect "mov %ah, ${0:h}", "=r,~{eax},~{ebx},~{ecx},~{edx},~{dirflag},~{fpsr},~{flags}"() + ret void +} +