From 5bd311bf17ffbf6a09ed68fbfeee94f6edb5a9a7 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 13 Nov 2014 17:58:48 +0000 Subject: [PATCH] ARM: add @llvm.arm.space intrinsic for testing ConstantIslands. Creating tests for the ConstantIslands pass is very difficult, since it depends on precise layout details. Having the ability to precisely inject a number of bytes into the stream helps greatly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221903 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsARM.td | 5 +++++ lib/Target/ARM/ARMAsmPrinter.cpp | 3 +++ lib/Target/ARM/ARMBaseInstrInfo.cpp | 2 ++ lib/Target/ARM/ARMInstrInfo.td | 5 +++++ test/CodeGen/ARM/space-directive.ll | 19 +++++++++++++++++++ 5 files changed, 34 insertions(+) create mode 100644 test/CodeGen/ARM/space-directive.ll diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index bc5cbf144e1..ce758e25731 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -20,6 +20,11 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">, Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; +// A space-consuming intrinsic primarily for testing ARMConstantIslands. The +// first argument is the number of bytes this "instruction" takes up, the second +// and return value are essentially chains, used to force ordering during ISel. +def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; + //===----------------------------------------------------------------------===// // Saturating Arithmetic diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index f8e32634c74..695fd4d16c5 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1592,6 +1592,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { EmitJumpTable(MI); return; } + case ARM::SPACE: + OutStreamer.EmitZeros(MI->getOperand(1).getImm()); + return; case ARM::TRAP: { // Non-Darwin binutils don't yet support the "trap" mnemonic. // FIXME: Remove this special case when they do. diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 4ab05f910ff..7a315c4b2ef 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -674,6 +674,8 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { ++NumEntries; return NumEntries * EntrySize + InstSize; } + case ARM::SPACE: + return MI->getOperand(1).getImm(); } } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c03901cb5e5..31771144612 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -5621,3 +5621,8 @@ def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm", // is discarded. def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>, ComplexDeprecationPredicate<"IT">; + +let mayLoad = 1, mayStore =1, hasSideEffects = 1 in +def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn), + NoItinerary, + [(set GPR:$Rd, (int_arm_space imm:$size, GPR:$Rn))]>; diff --git a/test/CodeGen/ARM/space-directive.ll b/test/CodeGen/ARM/space-directive.ll new file mode 100644 index 00000000000..55be1991fe8 --- /dev/null +++ b/test/CodeGen/ARM/space-directive.ll @@ -0,0 +1,19 @@ +; RUN: llc -mtriple=armv7 -o - %s | FileCheck %s + +define i32 @test_space() minsize { +; CHECK-LABEL: test_space: +; CHECK: ldr {{r[0-9]+}}, [[CPENTRY:.?LCPI[0-9]+_[0-9]+]] +; CHECK: b [[PAST_CP:.?LBB[0-9]+_[0-9]+]] + +; CHECK: [[CPENTRY]]: +; CHECK-NEXT: 12345678 + +; CHECK: [[PAST_CP]]: +; CHECK: .zero 10000 + %addr = inttoptr i32 12345678 to i32* + %val = load i32* %addr + call i32 @llvm.arm.space(i32 10000, i32 undef) + ret i32 %val +} + +declare i32 @llvm.arm.space(i32, i32)