OLD | NEW |
(Empty) | |
| 1 ; RUN: not pnacl-abicheck < %s | FileCheck %s |
| 2 |
| 3 ; Test the "align" attributes that are allowed on load and store |
| 4 ; instructions. |
| 5 |
| 6 |
| 7 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) |
| 8 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) |
| 9 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) |
| 10 |
| 11 |
| 12 define internal void @allowed_cases(i32 %ptr, float %f, double %d) { |
| 13 %ptr.i32 = inttoptr i32 %ptr to i32* |
| 14 load i32* %ptr.i32, align 1 |
| 15 store i32 123, i32* %ptr.i32, align 1 |
| 16 |
| 17 %ptr.float = inttoptr i32 %ptr to float* |
| 18 load float* %ptr.float, align 1 |
| 19 load float* %ptr.float, align 4 |
| 20 store float %f, float* %ptr.float, align 1 |
| 21 store float %f, float* %ptr.float, align 4 |
| 22 |
| 23 %ptr.double = inttoptr i32 %ptr to double* |
| 24 load double* %ptr.double, align 1 |
| 25 load double* %ptr.double, align 8 |
| 26 store double %d, double* %ptr.double, align 1 |
| 27 store double %d, double* %ptr.double, align 8 |
| 28 |
| 29 ; memcpy() et el take an alignment parameter, which is allowed to be 1. |
| 30 %ptr.p = inttoptr i32 %ptr to i8* |
| 31 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %ptr.p, i8* %ptr.p, |
| 32 i32 10, i32 1, i1 false) |
| 33 call void @llvm.memmove.p0i8.p0i8.i32(i8* %ptr.p, i8* %ptr.p, |
| 34 i32 10, i32 1, i1 false) |
| 35 call void @llvm.memset.p0i8.i32(i8* %ptr.p, i8 99, |
| 36 i32 10, i32 1, i1 false) |
| 37 |
| 38 ret void |
| 39 } |
| 40 ; CHECK-NOT: disallowed |
| 41 |
| 42 |
| 43 define internal void @rejected_cases(i32 %ptr, float %f, double %d, i32 %align)
{ |
| 44 %ptr.i32 = inttoptr i32 %ptr to i32* |
| 45 load i32* %ptr.i32, align 4 |
| 46 store i32 123, i32* %ptr.i32, align 4 |
| 47 ; CHECK: disallowed: bad alignment: {{.*}} load i32{{.*}} align 4 |
| 48 ; CHECK-NEXT: disallowed: bad alignment: store i32{{.*}} align 4 |
| 49 |
| 50 ; Unusual, not-very-useful alignments are rejected. |
| 51 %ptr.float = inttoptr i32 %ptr to float* |
| 52 load float* %ptr.float, align 2 |
| 53 load float* %ptr.float, align 8 |
| 54 store float %f, float* %ptr.float, align 2 |
| 55 store float %f, float* %ptr.float, align 8 |
| 56 ; CHECK-NEXT: disallowed: bad alignment: {{.*}} load float{{.*}} align 2 |
| 57 ; CHECK-NEXT: disallowed: bad alignment: {{.*}} load float{{.*}} align 8 |
| 58 ; CHECK-NEXT: disallowed: bad alignment: store float{{.*}} align 2 |
| 59 ; CHECK-NEXT: disallowed: bad alignment: store float{{.*}} align 8 |
| 60 |
| 61 %ptr.double = inttoptr i32 %ptr to double* |
| 62 load double* %ptr.double, align 2 |
| 63 load double* %ptr.double, align 4 |
| 64 store double %d, double* %ptr.double, align 2 |
| 65 store double %d, double* %ptr.double, align 4 |
| 66 ; CHECK-NEXT: disallowed: bad alignment: {{.*}} load double{{.*}} align 2 |
| 67 ; CHECK-NEXT: disallowed: bad alignment: {{.*}} load double{{.*}} align 4 |
| 68 ; CHECK-NEXT: disallowed: bad alignment: store double{{.*}} align 2 |
| 69 ; CHECK-NEXT: disallowed: bad alignment: store double{{.*}} align 4 |
| 70 |
| 71 ; Non-pessimistic alignments for memcpy() et al are rejected. |
| 72 %ptr.p = inttoptr i32 %ptr to i8* |
| 73 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %ptr.p, i8* %ptr.p, |
| 74 i32 10, i32 4, i1 false) |
| 75 call void @llvm.memmove.p0i8.p0i8.i32(i8* %ptr.p, i8* %ptr.p, |
| 76 i32 10, i32 4, i1 false) |
| 77 call void @llvm.memset.p0i8.i32(i8* %ptr.p, i8 99, |
| 78 i32 10, i32 4, i1 false) |
| 79 ; CHECK-NEXT: bad alignment: call void @llvm.memcpy |
| 80 ; CHECK-NEXT: bad alignment: call void @llvm.memmove |
| 81 ; CHECK-NEXT: bad alignment: call void @llvm.memset |
| 82 |
| 83 ; Check that the verifier does not crash if the alignment argument |
| 84 ; is not a constant. |
| 85 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %ptr.p, i8* %ptr.p, |
| 86 i32 10, i32 %align, i1 false) |
| 87 call void @llvm.memmove.p0i8.p0i8.i32(i8* %ptr.p, i8* %ptr.p, |
| 88 i32 10, i32 %align, i1 false) |
| 89 call void @llvm.memset.p0i8.i32(i8* %ptr.p, i8 99, |
| 90 i32 10, i32 %align, i1 false) |
| 91 ; CHECK-NEXT: bad alignment: call void @llvm.memcpy |
| 92 ; CHECK-NEXT: bad alignment: call void @llvm.memmove |
| 93 ; CHECK-NEXT: bad alignment: call void @llvm.memset |
| 94 |
| 95 ret void |
| 96 } |
| 97 ; CHECK-NOT: disallowed |
| 98 |
| 99 |
| 100 ; This stops the verifier from complaining about the lack of an entry point. |
| 101 define void @_start(i32 %arg) { |
| 102 ret void |
| 103 } |
OLD | NEW |