diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 2e938ae2e286..9b0ef8a5343a 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -580,20 +580,24 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) { .addReg(ScratchReg) .addImm((CallTarget >> 32) & 0xFFFF)); ++EncodedBytes; + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC) .addReg(ScratchReg) .addReg(ScratchReg) .addImm(32).addImm(16)); ++EncodedBytes; + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8) .addReg(ScratchReg) .addReg(ScratchReg) .addImm((CallTarget >> 16) & 0xFFFF)); ++EncodedBytes; + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8) .addReg(ScratchReg) .addReg(ScratchReg) .addImm(CallTarget & 0xFFFF)); + ++EncodedBytes; // Save the current TOC pointer before the remote call. int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset(); @@ -614,6 +618,7 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) { .addImm(8) .addReg(ScratchReg)); ++EncodedBytes; + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) .addReg(ScratchReg) .addImm(0) @@ -624,6 +629,7 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) { EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8) .addReg(ScratchReg)); ++EncodedBytes; + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8)); ++EncodedBytes; @@ -649,8 +655,10 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) { // Emit padding. unsigned NumBytes = Opers.getNumPatchBytes(); - assert(NumBytes >= EncodedBytes && - "Patchpoint can't request size less than the length of a call."); + if (NumBytes < EncodedBytes) + reportFatalUsageError( + "Patchpoint can't request size less than the length of a call."); + assert((NumBytes - EncodedBytes) % 4 == 0 && "Invalid number of NOP bytes requested!"); for (unsigned i = EncodedBytes; i < NumBytes; i += 4) diff --git a/llvm/test/CodeGen/PowerPC/ppc64-patchpoint-size-check.ll b/llvm/test/CodeGen/PowerPC/ppc64-patchpoint-size-check.ll new file mode 100644 index 000000000000..d38846f200d4 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/ppc64-patchpoint-size-check.ll @@ -0,0 +1,15 @@ +; RUN: not llc -mtriple=powerpc64-unknown-linux -verify-machineinstrs 2>&1 < %s | FileCheck %s + +define void @func(i64 %a, i64 %b) { +entry: + %test = icmp slt i64 %a, %b + br i1 %test, label %ret, label %cold +cold: + %thunk = inttoptr i64 244837814094590 to ptr + call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 36, ptr %thunk, i32 0, i64 %a, i64 %b) + unreachable +ret: + ret void +} + +; CHECK: LLVM ERROR: Patchpoint can't request size less than the length of a call.