diff options
author | Prakhar Bahuguna <prakhar.bahuguna@arm.com> | 2016-12-15 07:59:08 +0000 |
---|---|---|
committer | Prakhar Bahuguna <prakhar.bahuguna@arm.com> | 2016-12-15 07:59:08 +0000 |
commit | 52a7dd7d7825b269ae569db0e2bcb193c7698666 (patch) | |
tree | 7957bd2c8f0c07fbbcfdc331ca848a051dab6613 /llvm/test | |
parent | 342beeb91eb03ce92e598d593325c8475673768e (diff) | |
download | bcm5719-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.ll | 110 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/execute-only-big-stack-frame.ll | 46 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/execute-only-section.ll | 23 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/execute-only.ll | 82 | ||||
-rw-r--r-- | llvm/test/MC/ELF/ARM/execute-only-section.s | 44 |
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: } |