diff options
author | Mark Seaborn <mseaborn@chromium.org> | 2013-06-20 14:49:57 -0700 |
---|---|---|
committer | Mark Seaborn <mseaborn@chromium.org> | 2013-06-20 14:49:57 -0700 |
commit | 402eecfe0abd2f99580d81440f264067095b7a43 (patch) | |
tree | fe58b1ab2ec7d7696db6d27f4eccb9b4a7cd7e58 /test/NaCl | |
parent | 3f6504d96476bc8f717f077eda7a7061cb7672da (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.ll | 83 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-stripped-pointers.ll | 14 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/instructions.ll | 4 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/types-function.ll | 2 |
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) |