summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorPrakhar Bahuguna <prakhar.bahuguna@arm.com>2016-12-15 07:59:08 +0000
committerPrakhar Bahuguna <prakhar.bahuguna@arm.com>2016-12-15 07:59:08 +0000
commit52a7dd7d7825b269ae569db0e2bcb193c7698666 (patch)
tree7957bd2c8f0c07fbbcfdc331ca848a051dab6613 /llvm/test
parent342beeb91eb03ce92e598d593325c8475673768e (diff)
downloadbcm5719-llvm-52a7dd7d7825b269ae569db0e2bcb193c7698666.tar.gz
bcm5719-llvm-52a7dd7d7825b269ae569db0e2bcb193c7698666.zip
[ARM] Implement execute-only support in CodeGen
This implements execute-only support for ARM code generation, which prevents the compiler from generating data accesses to code sections. The following changes are involved: * Add the CodeGen option "-arm-execute-only" to the ARM code generator. * Add the clang flag "-mexecute-only" as well as the GCC-compatible alias "-mpure-code" to enable this option. * When enabled, literal pools are replaced with MOVW/MOVT instructions, with VMOV used in addition for floating-point literals. As the MOVT instruction is required, execute-only support is only available in Thumb mode for targets supporting ARMv8-M baseline or Thumb2. * Jump tables are placed in data sections when in execute-only mode. * The execute-only text section is assigned section ID 0, and is marked as unreadable with the SHF_ARM_PURECODE flag with symbol 'y'. This also overrides selection of ELF sections for globals. llvm-svn: 289784
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/ARM/constantfp.ll110
-rw-r--r--llvm/test/CodeGen/ARM/execute-only-big-stack-frame.ll46
-rw-r--r--llvm/test/CodeGen/ARM/execute-only-section.ll23
-rw-r--r--llvm/test/CodeGen/ARM/execute-only.ll82
-rw-r--r--llvm/test/MC/ELF/ARM/execute-only-section.s44
5 files changed, 305 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/ARM/constantfp.ll b/llvm/test/CodeGen/ARM/constantfp.ll
index 27b6e9b904d..b5aeadc05eb 100644
--- a/llvm/test/CodeGen/ARM/constantfp.ll
+++ b/llvm/test/CodeGen/ARM/constantfp.ll
@@ -2,6 +2,25 @@
; RUN: llc -mtriple=armv7 -mattr=+neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEONFP %s
; RUN: llc -mtriple=armv7 -mattr=-neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEON %s
+; RUN: llc -mtriple=thumbv7m -mcpu=cortex-m4 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s
+
+; RUN: llc -mtriple=thumbv7m -arm-execute-only -mcpu=cortex-m4 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s
+
+; RUN: llc -mtriple=thumbv7meb -arm-execute-only -mcpu=cortex-m4 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s
+
+; RUN: llc -mtriple=thumbv8m.main -mattr=fp-armv8 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s
+
+; RUN: llc -mtriple=thumbv8m.main -arm-execute-only -mattr=fp-armv8 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s
+
+; RUN: llc -mtriple=thumbv8m.maineb -arm-execute-only -mattr=fp-armv8 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s
+
+
define arm_aapcs_vfpcc float @test_vmov_f32() {
; CHECK-LABEL: test_vmov_f32:
; CHECK: vmov.f32 d0, #1.0
@@ -16,6 +35,14 @@ define arm_aapcs_vfpcc float @test_vmov_imm() {
; CHECK-NONEON-LABEL: test_vmov_imm:
; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-NO-XO-LABEL: test_vmov_imm:
+; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-FLOAT-LABEL: test_vmov_imm:
+; CHECK-XO-FLOAT: movs [[REG:r[0-9]+]], #0
+; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]
+; CHECK-XO-FLOAT-NOT: vldr
ret float 0.0
}
@@ -25,6 +52,14 @@ define arm_aapcs_vfpcc float @test_vmvn_imm() {
; CHECK-NONEON-LABEL: test_vmvn_imm:
; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-NO-XO-LABEL: test_vmvn_imm:
+; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-FLOAT-LABEL: test_vmvn_imm:
+; CHECK-XO-FLOAT: mvn [[REG:r[0-9]+]], #-1342177280
+; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]
+; CHECK-XO-FLOAT-NOT: vldr
ret float 8589934080.0
}
@@ -44,6 +79,19 @@ define arm_aapcs_vfpcc double @test_vmov_double_imm() {
; CHECK-NONEON-LABEL: test_vmov_double_imm:
; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-NO-XO-LABEL: test_vmov_double_imm:
+; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-DOUBLE-LABEL: test_vmov_double_imm:
+; CHECK-XO-DOUBLE: movs [[REG:r[0-9]+]], #0
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]]
+; CHECK-XO-DOUBLE-NOT: vldr
+
+; CHECK-XO-DOUBLE-BE-LABEL: test_vmov_double_imm:
+; CHECK-XO-DOUBLE-BE: movs [[REG:r[0-9]+]], #0
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG]], [[REG]]
+; CHECK-XO-DOUBLE-NOT: vldr
ret double 0.0
}
@@ -53,6 +101,19 @@ define arm_aapcs_vfpcc double @test_vmvn_double_imm() {
; CHECK-NONEON-LABEL: test_vmvn_double_imm:
; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-NO-XO-LABEL: test_vmvn_double_imm:
+; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-DOUBLE-LABEL: test_vmvn_double_imm:
+; CHECK-XO-DOUBLE: mvn [[REG:r[0-9]+]], #-1342177280
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]]
+; CHECK-XO-DOUBLE-NOT: vldr
+
+; CHECK-XO-DOUBLE-BE-LABEL: test_vmvn_double_imm:
+; CHECK-XO-DOUBLE-BE: mvn [[REG:r[0-9]+]], #-1342177280
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG]], [[REG]]
+; CHECK-XO-DOUBLE-BE-NOT: vldr
ret double 0x4fffffff4fffffff
}
@@ -64,5 +125,54 @@ define arm_aapcs_vfpcc double @test_notvmvn_double_imm() {
; CHECK-NONEON-LABEL: test_notvmvn_double_imm:
; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-NO-XO-LABEL: test_notvmvn_double_imm:
+; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-DOUBLE-LABEL: test_notvmvn_double_imm:
+; CHECK-XO-DOUBLE: mvn [[REG1:r[0-9]+]], #-1342177280
+; CHECK-XO-DOUBLE: mov.w [[REG2:r[0-9]+]], #-1
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
+; CHECK-XO-DOUBLE-NOT: vldr
+
+; CHECK-XO-DOUBLE-BE-LABEL: test_notvmvn_double_imm:
+; CHECK-XO-DOUBLE-BE: mov.w [[REG1:r[0-9]+]], #-1
+; CHECK-XO-DOUBLE-BE: mvn [[REG2:r[0-9]+]], #-1342177280
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
+; CHECK-XO-DOUBLE-BE-NOT: vldr
ret double 0x4fffffffffffffff
}
+
+define arm_aapcs_vfpcc float @lower_const_f32_xo() {
+; CHECK-NO-XO-LABEL: lower_const_f32_xo
+; CHECK-NO-XO: vldr {{s[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-FLOAT-LABEL: lower_const_f32_xo
+; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], #29884
+; CHECK-XO-FLOAT: movt [[REG]], #16083
+; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]
+; CHECK-XO-FLOAT-NOT: vldr
+ ret float 0x3FDA6E9780000000
+}
+
+define arm_aapcs_vfpcc double @lower_const_f64_xo() {
+; CHECK-NO-XO-LABEL: lower_const_f64_xo
+; CHECK-NO-XO: vldr {{d[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}}
+
+; CHECK-XO-DOUBLE-LABEL: lower_const_f64_xo
+; CHECK-XO-DOUBLE: movw [[REG1:r[0-9]+]], #6291
+; CHECK-XO-DOUBLE: movw [[REG2:r[0-9]+]], #27263
+; CHECK-XO-DOUBLE: movt [[REG1]], #16340
+; CHECK-XO-DOUBLE: movt [[REG2]], #29884
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
+; CHECK-XO-DOUBLE-NOT: vldr
+
+; CHECK-XO-DOUBLE-BE-LABEL: lower_const_f64_xo
+; CHECK-XO-DOUBLE-BE: movw [[REG1:r[0-9]+]], #27263
+; CHECK-XO-DOUBLE-BE: movw [[REG2:r[0-9]+]], #6291
+; CHECK-XO-DOUBLE-BE: movt [[REG1]], #29884
+; CHECK-XO-DOUBLE-BE: movt [[REG2]], #16340
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]
+; CHECK-XO-DOUBLE-BE-NOT: vldr
+ ret double 3.140000e-01
+}
diff --git a/llvm/test/CodeGen/ARM/execute-only-big-stack-frame.ll b/llvm/test/CodeGen/ARM/execute-only-big-stack-frame.ll
new file mode 100644
index 00000000000..fb498a81e39
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/execute-only-big-stack-frame.ll
@@ -0,0 +1,46 @@
+; RUN: llc < %s -mtriple=thumbv7m -arm-execute-only -O0 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-SUBW-ADDW %s
+; RUN: llc < %s -mtriple=thumbv8m.base -arm-execute-only -O0 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-MOVW-MOVT-ADD %s
+; RUN: llc < %s -mtriple=thumbv8m.main -arm-execute-only -O0 %s -o - \
+; RUN: | FileCheck --check-prefix=CHECK-SUBW-ADDW %s
+
+define i8 @test_big_stack_frame() {
+; CHECK-SUBW-ADDW-LABEL: test_big_stack_frame:
+; CHECK-SUBW-ADDW-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-SUBW-ADDW: sub.w sp, sp, #65536
+; CHECK-SUBW-ADDW-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-SUBW-ADDW: add.w [[REG1:r[0-9]+]], sp, #255
+; CHECK-SUBW-ADDW: add.w {{r[0-9]+}}, [[REG1]], #65280
+; CHECK-SUBW-ADDW-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-SUBW-ADDW: add.w lr, sp, #61440
+; CHECK-SUBW-ADDW-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-SUBW-ADDW: add.w sp, sp, #65536
+
+; CHECK-MOVW-MOVT-ADD-LABEL: test_big_stack_frame:
+; CHECK-MOVW-MOVT-ADD-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-MOVW-MOVT-ADD: movw [[REG1:r[0-9]+]], #0
+; CHECK-MOVW-MOVT-ADD: movt [[REG1]], #65535
+; CHECK-MOVW-MOVT-ADD: add sp, [[REG1]]
+; CHECK-MOVW-MOVT-ADD-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-MOVW-MOVT-ADD: movw [[REG2:r[0-9]+]], #65532
+; CHECK-MOVW-MOVT-ADD: movt [[REG2]], #0
+; CHECK-MOVW-MOVT-ADD: add [[REG2]], sp
+; CHECK-MOVW-MOVT-ADD-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-MOVW-MOVT-ADD: movw [[REG3:r[0-9]+]], #65532
+; CHECK-MOVW-MOVT-ADD: movt [[REG3]], #0
+; CHECK-MOVW-MOVT-ADD: add [[REG3]], sp
+; CHECK-MOVW-MOVT-ADD-NOT: ldr {{r[0-9]+}}, .{{.*}}
+; CHECK-MOVW-MOVT-ADD: movw [[REG4:r[0-9]+]], #0
+; CHECK-MOVW-MOVT-ADD: movt [[REG4]], #1
+; CHECK-MOVW-MOVT-ADD: add sp, [[REG4]]
+
+entry:
+ %s1 = alloca i8
+ %buffer = alloca [65528 x i8], align 1
+ call void @foo(i8* %s1)
+ %load = load i8, i8* %s1
+ ret i8 %load
+}
+
+declare void @foo(i8*)
diff --git a/llvm/test/CodeGen/ARM/execute-only-section.ll b/llvm/test/CodeGen/ARM/execute-only-section.ll
new file mode 100644
index 00000000000..6e1973cd0f1
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/execute-only-section.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s -mtriple=thumbv7m -arm-execute-only %s -o - | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv8m.base -arm-execute-only %s -o - | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv8m.main -arm-execute-only %s -o - | FileCheck %s
+
+; CHECK: .section .text,"axy",%progbits,unique,0
+; CHECK-NOT: .section
+; CHECK-NOT: .text
+; CHECK: .globl test_SectionForGlobal
+; CHECK: .type test_SectionForGlobal,%function
+define void @test_SectionForGlobal() {
+entry:
+ ret void
+}
+
+; CHECK: .section .test,"axy",%progbits
+; CHECK-NOT: .section
+; CHECK-NOT: .text
+; CHECK: .globl test_ExplicitSectionForGlobal
+; CHECK: .type test_ExplicitSectionForGlobal,%function
+define void @test_ExplicitSectionForGlobal() section ".test" {
+entry:
+ ret void
+}
diff --git a/llvm/test/CodeGen/ARM/execute-only.ll b/llvm/test/CodeGen/ARM/execute-only.ll
new file mode 100644
index 00000000000..1f9e8bf2813
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/execute-only.ll
@@ -0,0 +1,82 @@
+; RUN: llc -mtriple=thumbv8m.base-eabi -arm-execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2BASE %s
+; RUN: llc -mtriple=thumbv7m-eabi -arm-execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2 %s
+; RUN: llc -mtriple=thumbv8m.main-eabi -arm-execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2 %s
+
+@var = global i32 0
+
+define i32 @global() minsize {
+; CHECK-LABEL: global:
+; CHECK: movw [[GLOBDEST:r[0-9]+]], :lower16:var
+; CHECK: movt [[GLOBDEST]], :upper16:var
+
+ %val = load i32, i32* @var
+ ret i32 %val
+}
+
+define i32 @jump_table(i32 %c, i32 %a, i32 %b) #0 {
+; CHECK-LABEL: jump_table:
+; CHECK-T2: adr.w [[REG_JT:r[0-9]+]], .LJTI1_0
+; CHECK-T2: add.w [[REG_ENTRY:r[0-9]+]], [[REG_JT]], {{r[0-9]+}}, lsl #2
+; CHECK-T2: mov pc, [[REG_ENTRY]]
+
+; CHECK-T2BASE: lsls [[REG_OFFSET:r[0-9]+]], {{r[0-9]+}}, #2
+; CHECK-T2BASE: adr [[REG_JT:r[0-9]+]], .LJTI1_0
+; CHECK-T2BASE: adds [[REG_ENTRY:r[0-9]+]], [[REG_OFFSET]], [[REG_JT]]
+; CHECK-T2BASE: mov pc, [[REG_ENTRY]]
+
+; CHECK-LABEL: .LJTI1_0:
+; CHECK-NEXT: b.w
+; CHECK-NEXT: b.w
+; CHECK-NEXT: b.w
+; CHECK-NEXT: b.w
+; CHECK-NEXT: b.w
+; CHECK-NEXT: b.w
+
+entry:
+ switch i32 %c, label %return [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ i32 3, label %sw.bb3
+ i32 4, label %sw.bb4
+ i32 5, label %sw.bb6
+ i32 6, label %sw.bb8
+ ]
+
+sw.bb: ; preds = %entry
+ %add = add nsw i32 %a, 6
+ br label %return
+
+sw.bb1: ; preds = %entry
+ %add2 = add nsw i32 %a, 4
+ br label %return
+
+sw.bb3: ; preds = %entry
+ %sub = add nsw i32 %a, -3
+ br label %return
+
+sw.bb4: ; preds = %entry
+ %add5 = add nsw i32 %b, 5
+ br label %return
+
+sw.bb6: ; preds = %entry
+ %add7 = add nsw i32 %a, 1
+ br label %return
+
+sw.bb8: ; preds = %entry
+ %add9 = add nsw i32 %a, 2
+ br label %return
+
+return: ; preds = %entry, %sw.bb8, %sw.bb6, %sw.bb4, %sw.bb3, %sw.bb1, %sw.bb
+ %retval.0 = phi i32 [ %add9, %sw.bb8 ], [ %add7, %sw.bb6 ], [ %add5, %sw.bb4 ], [ %sub, %sw.bb3 ], [ %add2, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+}
+
+@.str = private unnamed_addr constant [4 x i8] c"FOO\00", align 1
+
+define hidden i8* @string_literal() {
+entry:
+; CHECK-LABEL: string_literal:
+; CHECK-NOT: .asciz
+; CHECK: .fnend
+ ret i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0)
+}
diff --git a/llvm/test/MC/ELF/ARM/execute-only-section.s b/llvm/test/MC/ELF/ARM/execute-only-section.s
new file mode 100644
index 00000000000..600ef5a41fd
--- /dev/null
+++ b/llvm/test/MC/ELF/ARM/execute-only-section.s
@@ -0,0 +1,44 @@
+// RUN: llvm-mc -filetype=obj -triple thumbv7m-arm-linux-gnu %s -o - \
+// RUN: | llvm-readobj -s -t | FileCheck %s
+
+ .section .text,"axy",%progbits,unique,0
+ .globl foo
+ .align 2
+ .type foo,%function
+ .code 16
+ .thumb_func
+foo:
+ .fnstart
+ bx lr
+.Lfunc_end0:
+ .size foo, .Lfunc_end0-foo
+ .fnend
+
+ .section ".note.GNU-stack","",%progbits
+
+
+// CHECK: Section {
+// CHECK: Name: .text (16)
+// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-NEXT: Flags [ (0x6)
+// CHECK-NEXT: SHF_ALLOC (0x2)
+// CHECK-NEXT: SHF_EXECINSTR (0x4)
+// CHECK-NEXT: ]
+// CHECK: Size: 0
+// CHECK: }
+
+// CHECK: Section {
+// CHECK: Name: .text (16)
+// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-NEXT: Flags [ (0x20000006)
+// CHECK-NEXT: SHF_ALLOC (0x2)
+// CHECK-NEXT: SHF_ARM_PURECODE (0x20000000)
+// CHECK-NEXT: SHF_EXECINSTR (0x4)
+// CHECK-NEXT: ]
+// CHECK: Size: 2
+// CHECK: }
+
+// CHECK: Symbol {
+// CHECK: Name: foo (22)
+// CHECK: Section: .text (0x3)
+// CHECK: }
OpenPOWER on IntegriCloud