ARM: add @llvm.arm.space intrinsic for testing ConstantIslands.
authorTim Northover <tnorthover@apple.com>
Thu, 13 Nov 2014 17:58:48 +0000 (17:58 +0000)
committerTim Northover <tnorthover@apple.com>
Thu, 13 Nov 2014 17:58:48 +0000 (17:58 +0000)
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
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMInstrInfo.td
test/CodeGen/ARM/space-directive.ll [new file with mode: 0644]

index bc5cbf144e1158c3c118a3dfe658b67809a2c079..ce758e257312f6b0f016cfeb55935d8b885f06df 100644 (file)
@@ -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
 
index f8e32634c74f3837a822a506774192b3cf466df5..695fd4d16c562ddfc7895e24294f01e13bfe9a4f 100644 (file)
@@ -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.
index 4ab05f910ff33bb29cd70360f1b27ef97739e801..7a315c4b2ef5c27152ad3c86c30806dc6a97bfcf 100644 (file)
@@ -674,6 +674,8 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
       ++NumEntries;
     return NumEntries * EntrySize + InstSize;
   }
+  case ARM::SPACE:
+    return MI->getOperand(1).getImm();
   }
 }
 
index c03901cb5e5ac3a468018f32ae8db04f2eb86919..3177114461206ec570611582786b343435f7cdc7 100644 (file)
@@ -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 (file)
index 0000000..55be199
--- /dev/null
@@ -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)