From c6c9bc0cd895bdefcc68d72b36f3b564f4e88938 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 9 Mar 2017 23:36:26 +0000 Subject: [PATCH] GlobalISel: support trivial inlineasm calls. They're used for nefarious purposes by ObjC. llvm-svn: 297422 --- .../llvm/CodeGen/GlobalISel/IRTranslator.h | 2 ++ lib/CodeGen/GlobalISel/IRTranslator.cpp | 21 ++++++++++++++++++- .../AArch64/GlobalISel/arm64-irtranslator.ll | 9 ++++++++ test/CodeGen/AArch64/GlobalISel/inline-asm.ll | 4 ++-- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 74b0c8d63fd..174443d47a5 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -143,6 +143,8 @@ private: bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder); + bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder); + /// Translate call instruction. /// \pre \p U is a call instruction. bool translateCall(const User &U, MachineIRBuilder &MIRBuilder); diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index e170b762ab8..b2ab3c12bc1 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -715,13 +715,32 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, return false; } +bool IRTranslator::translateInlineAsm(const CallInst &CI, + MachineIRBuilder &MIRBuilder) { + const InlineAsm &IA = cast(*CI.getCalledValue()); + if (!IA.getConstraintString().empty()) + return false; + + unsigned ExtraInfo = 0; + if (IA.hasSideEffects()) + ExtraInfo |= InlineAsm::Extra_HasSideEffects; + if (IA.getDialect() == InlineAsm::AD_Intel) + ExtraInfo |= InlineAsm::Extra_AsmDialect; + + MIRBuilder.buildInstr(TargetOpcode::INLINEASM) + .addExternalSymbol(IA.getAsmString().c_str()) + .addImm(ExtraInfo); + + return true; +} + bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) { const CallInst &CI = cast(U); auto TII = MF->getTarget().getIntrinsicInfo(); const Function *F = CI.getCalledFunction(); if (CI.isInlineAsm()) - return false; + return translateInlineAsm(CI, MIRBuilder); if (!F || !F->isIntrinsic()) { unsigned Res = CI.getType()->isVoidTy() ? 0 : getOrCreateVReg(CI); diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index c0cbf69a2e6..21ce631cca3 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1262,3 +1262,12 @@ define double @test_fneg_f64(double %x) { %neg = fsub double -0.000000e+00, %x ret double %neg } + +define void @test_trivial_inlineasm() { +; CHECK-LABEL: name: test_trivial_inlineasm +; CHECK: INLINEASM $wibble, 1 +; CHECK: INLINEASM $wibble, 0 + call void asm sideeffect "wibble", ""() + call void asm "wibble", ""() + ret void +} diff --git a/test/CodeGen/AArch64/GlobalISel/inline-asm.ll b/test/CodeGen/AArch64/GlobalISel/inline-asm.ll index 3dc8f8cb706..8ff7c4495dc 100644 --- a/test/CodeGen/AArch64/GlobalISel/inline-asm.ll +++ b/test/CodeGen/AArch64/GlobalISel/inline-asm.ll @@ -2,9 +2,9 @@ ; CHECK-LABEL: test_asm: ; CHECK: {{APP|InlineAsm Start}} -; CHECK: mov x0, x0 +; CHECK: mov x0, {{x[0-9]+}} ; CHECK: {{NO_APP|InlineAsm End}} define void @test_asm() { - call void asm sideeffect "mov x0, x0", ""() + call void asm sideeffect "mov x0, $0", "r"(i64 42) ret void }