Index: tests_lit/reader_tests/switch.ll |
diff --git a/tests_lit/reader_tests/switch.ll b/tests_lit/reader_tests/switch.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7edaeda5c69307968307ab790bb50c10f8dca02f |
--- /dev/null |
+++ b/tests_lit/reader_tests/switch.ll |
@@ -0,0 +1,496 @@ |
+; Test switch instructions. |
+ |
+; RUN: llvm-as < %s | pnacl-freeze -allow-local-symbol-tables \ |
+; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \ |
+; RUN: -allow-pnacl-reader-error-recovery \ |
+; RUN: -allow-local-symbol-tables \ |
+; RUN: | FileCheck %s |
+ |
+define void @testDefaultSwitch(i32 %a) { |
+entry: |
+ switch i32 %a, label %exit [ |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK: define void @testDefaultSwitch(i32 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i32 %a, label %exit [ |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define i32 @testSwitch(i32 %a) { |
+entry: |
+ switch i32 %a, label %sw.default [ |
+ i32 1, label %sw.epilog |
+ i32 2, label %sw.epilog |
+ i32 3, label %sw.epilog |
+ i32 7, label %sw.bb1 |
+ i32 8, label %sw.bb1 |
+ i32 15, label %sw.bb2 |
+ i32 14, label %sw.bb2 |
+ ] |
+ |
+sw.default: ; preds = %entry |
+ %add = add i32 %a, 27 |
+ br label %sw.epilog |
+ |
+sw.bb1: ; preds = %entry, %entry |
+ %phitmp = sub i32 21, %a |
+ br label %sw.bb2 |
+ |
+sw.bb2: ; preds = %sw.bb1, %entry, %entry |
+ %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ] |
+ br label %sw.epilog |
+ |
+sw.epilog: ; preds = %sw.bb2, %sw.default, %entry, %entry, %entry |
+ %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ] |
+ ret i32 %result.1 |
+} |
+ |
+; CHECK-NEXT: define i32 @testSwitch(i32 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i32 %a, label %sw.default [ |
+; CHECK-NEXT: i32 1, label %sw.epilog |
+; CHECK-NEXT: i32 2, label %sw.epilog |
+; CHECK-NEXT: i32 3, label %sw.epilog |
+; CHECK-NEXT: i32 7, label %sw.bb1 |
+; CHECK-NEXT: i32 8, label %sw.bb1 |
+; CHECK-NEXT: i32 15, label %sw.bb2 |
+; CHECK-NEXT: i32 14, label %sw.bb2 |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: sw.default: |
+; CHECK-NEXT: %add = add i32 %a, 27 |
+; CHECK-NEXT: br label %sw.epilog |
+; CHECK-NEXT: sw.bb1: |
+; CHECK-NEXT: %phitmp = sub i32 21, %a |
+; CHECK-NEXT: br label %sw.bb2 |
+; CHECK-NEXT: sw.bb2: |
+; CHECK-NEXT: %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ] |
+; CHECK-NEXT: br label %sw.epilog |
+; CHECK-NEXT: sw.epilog: |
+; CHECK-NEXT: %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ] |
+; CHECK-NEXT: ret i32 %result.1 |
+; CHECK-NEXT: } |
+ |
+define void @testSignedI32Values(i32 %a) { |
+entry: |
+ switch i32 %a, label %labelDefault [ |
+ i32 0, label %label0 |
+ i32 -1, label %labelM1 |
+ i32 3, label %labelOther |
+ i32 -3, label %labelOther |
+ i32 -2147483648, label %labelMin ; min signed i32 |
+ i32 2147483647, label %labelMax ; max signed i32 |
+ ] |
+labelDefault: |
+ ret void |
+label0: |
+ ret void |
+labelM1: |
+ ret void |
+labelMin: |
+ ret void |
+labelMax: |
+ ret void |
+labelOther: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI32Values(i32 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i32 %a, label %labelDefault [ |
+; CHECK-NEXT: i32 0, label %label0 |
+; CHECK-NEXT: i32 -1, label %labelM1 |
+; CHECK-NEXT: i32 3, label %labelOther |
+; CHECK-NEXT: i32 -3, label %labelOther |
+; CHECK-NEXT: i32 -2147483648, label %labelMin |
+; CHECK-NEXT: i32 2147483647, label %labelMax |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: labelDefault: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: label0: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: labelM1: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: labelMin: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: labelMax: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: labelOther: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross signed i32 size boundaries. |
+define void @testSignedI32Boundary(i32 %a) { |
+entry: |
+ switch i32 %a, label %exit [ |
+ i32 -2147483649, label %exit ; min signed i32 - 1 |
+ i32 2147483648, label %exit ; max signed i32 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI32Boundary(i32 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i32 %a, label %exit [ |
+; CHECK-NEXT: i32 2147483647, label %exit |
+; CHECK-NEXT: i32 -2147483648, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testUnsignedI32Values(i32 %a) { |
+entry: |
+ switch i32 %a, label %exit [ |
+ i32 0, label %exit |
+ i32 2147483647, label %exit ; max signed i32 |
+ i32 4294967295, label %exit ; max unsigned i32 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI32Values(i32 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i32 %a, label %exit [ |
+; CHECK-NEXT: i32 0, label %exit |
+; CHECK-NEXT: i32 2147483647, label %exit |
+; ; Note that -1 is signed version of 4294967295 |
+; CHECK-NEXT: i32 -1, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross unsigned i32 boundaries. |
+define void @testUnsignedI32Boundary(i32 %a) { |
+entry: |
+ switch i32 %a, label %exit [ |
+ i32 4294967296, label %exit ; max unsigned i32 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI32Boundary(i32 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i32 %a, label %exit [ |
+; CHECK-NEXT: i32 0, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testSignedI64Values(i64 %a) { |
+entry: |
+ switch i64 %a, label %exit [ |
+ i64 0, label %exit |
+ i64 -9223372036854775808, label %exit ; min signed i64 |
+ i64 9223372036854775807, label %exit ; max signed i64 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI64Values(i64 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i64 %a, label %exit [ |
+; CHECK-NEXT: i64 0, label %exit |
+; CHECK-NEXT: i64 -9223372036854775808, label %exit |
+; CHECK-NEXT: i64 9223372036854775807, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross signed i64 size boundaries. |
+define void @testSignedI64Boundary(i64 %a) { |
+entry: |
+ switch i64 %a, label %exit [ |
+ i64 0, label %exit |
+ i64 -9223372036854775809, label %exit ; min signed i64 - 1 |
+ i64 9223372036854775808, label %exit ; max signed i64 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI64Boundary(i64 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i64 %a, label %exit [ |
+; CHECK-NEXT: i64 0, label %exit |
+; CHECK-NEXT: i64 9223372036854775807, label %exit |
+; CHECK-NEXT: i64 -9223372036854775808, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testUnsignedI64Values(i64 %a) { |
+entry: |
+ switch i64 %a, label %exit [ |
+ i64 0, label %exit |
+ i64 9223372036854775807, label %exit ; max signed i64 |
+ i64 18446744073709551615, label %exit ; max unsigned i64 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI64Values(i64 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i64 %a, label %exit [ |
+; CHECK-NEXT: i64 0, label %exit |
+; CHECK-NEXT: i64 9223372036854775807, label %exit |
+; CHECK-NEXT: i64 -1, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross unsigned i64 size boundaries. |
+define void @testUnsignedI64Boundary(i64 %a) { |
+entry: |
+ switch i64 %a, label %exit [ |
+ i64 18446744073709551616, label %exit ; max unsigned i64 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI64Boundary(i64 %a) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: switch i64 %a, label %exit [ |
+; CHECK-NEXT: i64 0, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testSignedI16Values(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i16 |
+ switch i16 %a, label %exit [ |
+ i16 0, label %exit |
+ i16 -1, label %exit |
+ i16 3, label %exit |
+ i16 -3, label %exit |
+ i16 -32768, label %exit ; min signed i16 |
+ i16 32767, label %exit ; max unsigned i16 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI16Values(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i16 |
+; CHECK-NEXT: switch i16 %a, label %exit [ |
+; CHECK-NEXT: i16 0, label %exit |
+; CHECK-NEXT: i16 -1, label %exit |
+; CHECK-NEXT: i16 3, label %exit |
+; CHECK-NEXT: i16 -3, label %exit |
+; CHECK-NEXT: i16 -32768, label %exit |
+; CHECK-NEXT: i16 32767, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross signed i16 size boundaries. |
+define void @testSignedI16Boundary(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i16 |
+ switch i16 %a, label %exit [ |
+ i16 -32769, label %exit ; min signed i16 - 1 |
+ i16 32768, label %exit ; max unsigned i16 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI16Boundary(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i16 |
+; CHECK-NEXT: switch i16 %a, label %exit [ |
+; CHECK-NEXT: i16 32767, label %exit |
+; CHECK-NEXT: i16 -32768, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testUnsignedI16Values(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i16 |
+ switch i16 %a, label %exit [ |
+ i16 0, label %exit |
+ i16 32767, label %exit ; max signed i16 |
+ i16 65535, label %exit ; max unsigned i16 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI16Values(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i16 |
+; CHECK-NEXT: switch i16 %a, label %exit [ |
+; CHECK-NEXT: i16 0, label %exit |
+; CHECK-NEXT: i16 32767, label %exit |
+; ; Note that -1 is signed version of 65535 |
+; CHECK-NEXT: i16 -1, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross unsigned i16 size boundaries. |
+define void @testUnsignedI16Boundary(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i16 |
+ switch i16 %a, label %exit [ |
+ i16 65536, label %exit ; max unsigned i16 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI16Boundary(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i16 |
+; CHECK-NEXT: switch i16 %a, label %exit [ |
+; CHECK-NEXT: i16 0, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testSignedI8Values(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i8 |
+ switch i8 %a, label %exit [ |
+ i8 0, label %exit |
+ i8 -1, label %exit |
+ i8 3, label %exit |
+ i8 -3, label %exit |
+ i8 -128, label %exit ; min signed i8 |
+ i8 127, label %exit ; max unsigned i8 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI8Values(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i8 |
+; CHECK-NEXT: switch i8 %a, label %exit [ |
+; CHECK-NEXT: i8 0, label %exit |
+; CHECK-NEXT: i8 -1, label %exit |
+; CHECK-NEXT: i8 3, label %exit |
+; CHECK-NEXT: i8 -3, label %exit |
+; CHECK-NEXT: i8 -128, label %exit |
+; CHECK-NEXT: i8 127, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross signed i8 size boundaries. |
+define void @testSignedI8Boundary(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i8 |
+ switch i8 %a, label %exit [ |
+ i8 -129, label %exit ; min signed i8 - 1 |
+ i8 128, label %exit ; max unsigned i8 + 1 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testSignedI8Boundary(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i8 |
+; CHECK-NEXT: switch i8 %a, label %exit [ |
+; CHECK-NEXT: i8 127, label %exit |
+; CHECK-NEXT: i8 -128, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+ |
+define void @testUnsignedI8Values(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i8 |
+ switch i8 %a, label %exit [ |
+ i8 0, label %exit |
+ i8 127, label %exit ; max signed i8 |
+ i8 255, label %exit ; max unsigned i8 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI8Values(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i8 |
+; CHECK-NEXT: switch i8 %a, label %exit [ |
+; CHECK-NEXT: i8 0, label %exit |
+; CHECK-NEXT: i8 127, label %exit |
+; ; Note that -1 is signed version of 255 |
+; CHECK-NEXT: i8 -1, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+; Test values that cross unsigned i8 size boundaries. |
+define void @testUnsignedI8Boundary(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i8 |
+ switch i8 %a, label %exit [ |
+ i8 256, label %exit ; max unsigned i8 |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testUnsignedI8Boundary(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i8 |
+; CHECK-NEXT: switch i8 %a, label %exit [ |
+; CHECK-NEXT: i8 0, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |
+define void @testI1Values(i32 %p) { |
+entry: |
+ %a = trunc i32 %p to i1 |
+ switch i1 %a, label %exit [ |
+ i1 true, label %exit |
+ i1 false, label %exit |
+ ] |
+exit: |
+ ret void |
+} |
+ |
+; CHECK-NEXT: define void @testI1Values(i32 %p) { |
+; CHECK-NEXT: entry: |
+; CHECK-NEXT: %a = trunc i32 %p to i1 |
+; CHECK-NEXT: switch i1 %a, label %exit [ |
+; CHECK-NEXT: i1 -1, label %exit |
+; CHECK-NEXT: i1 0, label %exit |
+; CHECK-NEXT: ] |
+; CHECK-NEXT: exit: |
+; CHECK-NEXT: ret void |
+; CHECK-NEXT: } |
+ |