aboutsummaryrefslogtreecommitdiff
path: root/test/NaCl
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2013-06-20 14:49:57 -0700
committerMark Seaborn <mseaborn@chromium.org>2013-06-20 14:49:57 -0700
commit402eecfe0abd2f99580d81440f264067095b7a43 (patch)
treefe58b1ab2ec7d7696db6d27f4eccb9b4a7cd7e58 /test/NaCl
parent3f6504d96476bc8f717f077eda7a7061cb7672da (diff)
PNaCl ABI: Reduce the set of allowed "align" attributes on loads/stores
Change the ABI verifier to require "align 1" on non-atomic integer accesses to prevent non-portable behaviour. Allow larger alignments on floating point accesses as a concession to performance, because ARM might not be able to do unaligned FP loads/stores efficiently. Change StripAttributes to make pexes pass the ABI verifier. Also update comments in StripAttributes to match some recent changes. BUG=https://code.google.com/p/nativeclient/issues/detail?id=3445 TEST=*.ll tests + PNaCl toolchain trybots Review URL: https://codereview.chromium.org/17094009
Diffstat (limited to 'test/NaCl')
-rw-r--r--test/NaCl/PNaClABI/abi-alignment.ll83
-rw-r--r--test/NaCl/PNaClABI/abi-stripped-pointers.ll14
-rw-r--r--test/NaCl/PNaClABI/instructions.ll4
-rw-r--r--test/NaCl/PNaClABI/types-function.ll2
4 files changed, 93 insertions, 10 deletions
diff --git a/test/NaCl/PNaClABI/abi-alignment.ll b/test/NaCl/PNaClABI/abi-alignment.ll
new file mode 100644
index 0000000000..0ef1f86604
--- /dev/null
+++ b/test/NaCl/PNaClABI/abi-alignment.ll
@@ -0,0 +1,83 @@
+; RUN: pnacl-abicheck < %s | FileCheck %s
+
+; Test the "align" attributes that are allowed on load and store
+; instructions. Note that "cmpxchg" and "atomicrmw" do not take
+; "align" attributes, so are not tested here.
+
+
+define void @allowed_cases(i32 %ptr, float %f, double %d) {
+ %ptr.i32 = inttoptr i32 %ptr to i32*
+ load i32* %ptr.i32, align 1
+ store i32 123, i32* %ptr.i32, align 1
+
+ %ptr.float = inttoptr i32 %ptr to float*
+ load float* %ptr.float, align 1
+ load float* %ptr.float, align 4
+ store float %f, float* %ptr.float, align 1
+ store float %f, float* %ptr.float, align 4
+
+ %ptr.double = inttoptr i32 %ptr to double*
+ load double* %ptr.double, align 1
+ load double* %ptr.double, align 8
+ store double %d, double* %ptr.double, align 1
+ store double %d, double* %ptr.double, align 8
+
+ ; Stricter alignments are required for atomics.
+ load atomic i32* %ptr.i32 seq_cst, align 4
+ store atomic i32 123, i32* %ptr.i32 seq_cst, align 4
+ load atomic float* %ptr.float seq_cst, align 4
+ store atomic float %f, float* %ptr.float seq_cst, align 4
+ load atomic double* %ptr.double seq_cst, align 8
+ store atomic double %d, double* %ptr.double seq_cst, align 8
+
+ ret void
+}
+; CHECK-NOT: disallowed
+
+
+define void @rejected_cases(i32 %ptr, float %f, double %d) {
+ %ptr.i32 = inttoptr i32 %ptr to i32*
+ load i32* %ptr.i32, align 4
+ store i32 123, i32* %ptr.i32, align 4
+; CHECK: disallowed: bad alignment: {{.*}} load i32{{.*}} align 4
+; CHECK-NEXT: disallowed: bad alignment: store i32{{.*}} align 4
+
+ ; Unusual, not-very-useful alignments are rejected.
+ %ptr.float = inttoptr i32 %ptr to float*
+ load float* %ptr.float, align 2
+ load float* %ptr.float, align 8
+ store float %f, float* %ptr.float, align 2
+ store float %f, float* %ptr.float, align 8
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load float{{.*}} align 2
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load float{{.*}} align 8
+; CHECK-NEXT: disallowed: bad alignment: store float{{.*}} align 2
+; CHECK-NEXT: disallowed: bad alignment: store float{{.*}} align 8
+
+ %ptr.double = inttoptr i32 %ptr to double*
+ load double* %ptr.double, align 2
+ load double* %ptr.double, align 4
+ store double %d, double* %ptr.double, align 2
+ store double %d, double* %ptr.double, align 4
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load double{{.*}} align 2
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load double{{.*}} align 4
+; CHECK-NEXT: disallowed: bad alignment: store double{{.*}} align 2
+; CHECK-NEXT: disallowed: bad alignment: store double{{.*}} align 4
+
+ ; Too-small alignments for atomics are rejected.
+ load atomic i32* %ptr.i32 seq_cst, align 2
+ load atomic float* %ptr.float seq_cst, align 2
+ load atomic double* %ptr.double seq_cst, align 4
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load atomic i32{{.*}} align 2
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load atomic float{{.*}} align 2
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load atomic double{{.*}} align 4
+
+ ; Too-large alignments for atomics are also rejected.
+ load atomic i32* %ptr.i32 seq_cst, align 8
+ load atomic float* %ptr.float seq_cst, align 8
+ load atomic double* %ptr.double seq_cst, align 16
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load atomic i32{{.*}} align 8
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load atomic float{{.*}} align 8
+; CHECK-NEXT: disallowed: bad alignment: {{.*}} load atomic double{{.*}} align 16
+
+ ret void
+}
diff --git a/test/NaCl/PNaClABI/abi-stripped-pointers.ll b/test/NaCl/PNaClABI/abi-stripped-pointers.ll
index c994b7d009..d590d4902d 100644
--- a/test/NaCl/PNaClABI/abi-stripped-pointers.ll
+++ b/test/NaCl/PNaClABI/abi-stripped-pointers.ll
@@ -38,18 +38,18 @@ define void @allowed_cases(i32 %arg) {
ptrtoint [1 x i8]* %alloc to i32
; These instructions may use a NormalizedPtr, which may be a global.
- load i32* @ptr
- store i32 123, i32* @ptr
+ load i32* @ptr, align 1
+ store i32 123, i32* @ptr, align 1
cmpxchg i32* @ptr, i32 1, i32 2 seq_cst
atomicrmw add i32* @ptr, i32 3 seq_cst
; A NormalizedPtr may be a bitcast.
%ptr_bitcast = bitcast [4 x i8]* @var to i32*
- load i32* %ptr_bitcast
+ load i32* %ptr_bitcast, align 1
; A NormalizedPtr may be an inttoptr.
%ptr_from_int = inttoptr i32 123 to i32*
- load i32* %ptr_from_int
+ load i32* %ptr_from_int, align 1
; Check direct and indirect function calls.
%func_as_int = ptrtoint void ()* @func to i32
@@ -85,15 +85,15 @@ entry:
%a = alloca i32
; CHECK-NEXT: non-i8-array alloca
- store i32 0, i32* null
+ store i32 0, i32* null, align 1
; CHECK-NEXT: bad pointer
- store i32 0, i32* undef
+ store i32 0, i32* undef, align 1
; CHECK-NEXT: bad pointer
%bc = bitcast i32* @ptr to i31*
; CHECK-NEXT: bad result type
- store i31 0, i31* %bc
+ store i31 0, i31* %bc, align 1
; CHECK-NEXT: bad pointer
; Only one level of bitcasts is allowed.
diff --git a/test/NaCl/PNaClABI/instructions.ll b/test/NaCl/PNaClABI/instructions.ll
index b65829d865..11b344e5a7 100644
--- a/test/NaCl/PNaClABI/instructions.ll
+++ b/test/NaCl/PNaClABI/instructions.ll
@@ -73,8 +73,8 @@ define void @memory() {
; Memory operations
%a1 = alloca [4 x i8]
%ptr = inttoptr i32 0 to i32*
- %a2 = load i32* %ptr
- store i32 undef, i32* %ptr
+ %a2 = load i32* %ptr, align 1
+ store i32 undef, i32* %ptr, align 1
fence acq_rel
%a3 = cmpxchg i32* %ptr, i32 undef, i32 undef acq_rel
%a4 = atomicrmw add i32* %ptr, i32 1 acquire
diff --git a/test/NaCl/PNaClABI/types-function.ll b/test/NaCl/PNaClABI/types-function.ll
index 1482c727f0..a3fb55b23c 100644
--- a/test/NaCl/PNaClABI/types-function.ll
+++ b/test/NaCl/PNaClABI/types-function.ll
@@ -22,7 +22,7 @@ define void @types() {
%h3 = fadd double 0.0, fpext (half 0.0 to double)
; CHECK: bad pointer: store
- store i32 0, i32* bitcast (i17* @a2 to i32*), align 4
+ store i32 0, i32* bitcast (i17* @a2 to i32*), align 1
; CHECK: bad function callee operand: call void @func(i15 1)
call void @func(i15 1)