Index: test/NaCl/PNaClABI/types.ll |
diff --git a/test/NaCl/PNaClABI/types.ll b/test/NaCl/PNaClABI/types.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d5ca57739d922a70d836840fb7b5468365207971 |
--- /dev/null |
+++ b/test/NaCl/PNaClABI/types.ll |
@@ -0,0 +1,206 @@ |
+; RUN: not pnacl-abicheck < %s | FileCheck %s |
+; Test types allowed by PNaCl ABI |
+ |
+ |
+; CHECK: Function badReturn has disallowed type: half* () |
+define internal half* @badReturn() { |
+ unreachable |
+} |
+ |
+; CHECK: Function badArgType1 has disallowed type: void (half, i32) |
+define internal void @badArgType1(half %a, i32 %b) { |
+ ret void |
+} |
+; CHECK: Function badArgType2 has disallowed type: void (i32, half) |
+define internal void @badArgType2(i32 %a, half %b) { |
+ ret void |
+} |
+ |
+ |
+define internal void @func() { |
+entry: |
+ br label %block |
+block: |
+ |
+ ; We test for allowed/disallowed types via phi nodes. This gives us |
+ ; a uniform way to test any type. |
+ |
+ ; Allowed types |
+ |
+ ; Scalars. |
+ phi i1 [ undef, %entry ] |
+ phi i8 [ undef, %entry ] |
+ phi i16 [ undef, %entry ] |
+ phi i32 [ undef, %entry ] |
+ phi i64 [ undef, %entry ] |
+ phi float [ undef, %entry ] |
+ phi double [ undef, %entry ] |
+ ; Vectors. |
+ phi <4 x i1> [ undef, %entry ] |
+ phi <8 x i1> [ undef, %entry ] |
+ phi <16 x i1> [ undef, %entry ] |
+ phi <16 x i8> [ undef, %entry ] |
+ phi <8 x i16> [ undef, %entry ] |
+ phi <4 x i32> [ undef, %entry ] |
+ phi <4 x float> [ undef, %entry ] |
+; CHECK-NOT: disallowed |
+ |
+ |
+ ; Disallowed integer types |
+ |
+ phi i4 [ undef, %entry ] |
+; CHECK: Function func disallowed: bad operand: {{.*}} i4 |
+ |
+ phi i33 [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} i33 |
+ |
+ phi i128 [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} i128 |
+ |
+ |
+ ; Disallowed floating point types |
+ |
+ phi half [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} half |
+ |
+ phi x86_fp80 [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} x86_fp80 |
+ |
+ phi fp128 [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} fp128 |
+ |
+ phi ppc_fp128 [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} ppc_fp128 |
+ |
+ phi x86_mmx [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} x86_mmx |
+ |
+ |
+ ; Derived types are disallowed too |
+ |
+ phi i32* [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} i32* |
+ |
+ phi [1 x i32] [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} [1 x i32] |
+ |
+ phi { i32, float } [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} { i32, float } |
+ |
+ phi void (i32)* [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} void (i32)* |
+ |
+ phi <{ i8, i32 }> [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <{ i8, i32 }> |
+ |
+ ; Vector types of weird bit width are disallowed |
+ phi <1 x i1> [ undef, %entry ] |
+ phi <3 x i1> [ undef, %entry ] |
+ phi <17 x i1> [ undef, %entry ] |
+ phi <1 x i32> [ undef, %entry ] |
+ phi <2 x i32> [ undef, %entry ] |
+ phi <3 x i32> [ undef, %entry ] |
+ phi <5 x i32> [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <1 x i1> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <3 x i1> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <17 x i1> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <1 x i32> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <2 x i32> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <3 x i32> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <5 x i32> |
+ |
+ ; i64 and double vectors are currently disallowed, and so are the |
+ ; corresponding bool vectors. |
+ phi <2 x i1> [ undef, %entry ] |
+ phi <2 x i64> [ undef, %entry ] |
+ phi <2 x double> [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <2 x i1> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <2 x i64> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <2 x double> |
+ |
+ ; 256-bit width vectors are currently disallowed, and so are the |
+ ; corresponding bool vectors. |
+ phi <32 x i1> [ undef, %entry ] |
+ phi <32 x i8> [ undef, %entry ] |
+ phi <16 x i16> [ undef, %entry ] |
+ phi <8 x i32> [ undef, %entry ] |
+ phi <4 x i64> [ undef, %entry ] |
+ phi <8 x float> [ undef, %entry ] |
+ phi <4 x double> [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <32 x i1> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <32 x i8> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <16 x i16> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <8 x i32> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <4 x i64> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <8 x float> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <4 x double> |
+ |
+ ; 512-bit width vectors are currently disallowed, and so are the |
+ ; corresponding bool vectors. |
+ phi <64 x i1> [ undef, %entry ] |
+ phi <64 x i8> [ undef, %entry ] |
+ phi <32 x i16> [ undef, %entry ] |
+ phi <16 x i32> [ undef, %entry ] |
+ phi <8 x i64> [ undef, %entry ] |
+ phi <16 x float> [ undef, %entry ] |
+ phi <8 x double> [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <64 x i1> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <64 x i8> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <32 x i16> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <16 x i32> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <8 x i64> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <16 x float> |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <8 x double> |
+ |
+ ret void |
+} |
+ |
+ |
+; Named types. With the current implementation, named types are legal |
+; until they are actually attempted to be used. Might want to fix that. |
+%struct.s1 = type { half, float} |
+%struct.s2 = type { i32, i32} |
+ |
+define internal void @func2() { |
+entry: |
+ br label %block |
+block: |
+ |
+ phi %struct.s1 [ undef, %entry ] |
+; CHECK: disallowed: bad operand: {{.*}} %struct.s1 |
+ |
+ phi %struct.s2 [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} %struct.s2 |
+ |
+ ret void |
+} |
+ |
+ |
+; Circularities: here to make sure the verifier doesn't crash or assert. |
+ |
+; This oddity is perfectly legal according to the IR and ABI verifiers. |
+; Might want to fix that. (good luck initializing one of these, though.) |
+%struct.snake = type { i32, %struct.tail } |
+%struct.tail = type { %struct.snake, i32 } |
+ |
+%struct.linked = type { i32, %struct.linked * } |
+ |
+define internal void @func3() { |
+entry: |
+ br label %block |
+block: |
+ |
+ phi %struct.snake [ undef, %entry ] |
+; CHECK: disallowed: bad operand: {{.*}} %struct.snake |
+ |
+ phi %struct.linked [ undef, %entry ] |
+; CHECK-NEXT: disallowed: bad operand: {{.*}} %struct.linked |
+ |
+ ret void |
+} |
+ |
+ |
+; This stops the verifier from complaining about the lack of an entry point. |
+define void @_start(i32 %arg) { |
+ ret void |
+} |