aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/SimplifyCFG/X86
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/SimplifyCFG/X86')
-rw-r--r--test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll50
-rw-r--r--test/Transforms/SimplifyCFG/X86/switch-table-bug.ll41
-rw-r--r--test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll115
3 files changed, 201 insertions, 5 deletions
diff --git a/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll b/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll
new file mode 100644
index 0000000..22599b3
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll
@@ -0,0 +1,50 @@
+; RUN: opt -S -simplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
+; rdar://17887153
+target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin12.0.0"
+
+; When we have a covered lookup table, make sure we don't delete PHINodes that
+; are cached in PHIs.
+; CHECK-LABEL: @test
+; CHECK: entry:
+; CHECK-NEXT: sub i3 %arg, -4
+; CHECK-NEXT: zext i3 %switch.tableidx to i4
+; CHECK-NEXT: getelementptr inbounds [8 x i64]* @switch.table, i32 0, i4 %switch.tableidx.zext
+; CHECK-NEXT: load i64* %switch.gep
+; CHECK-NEXT: add i64
+; CHECK-NEXT: ret i64
+define i64 @test(i3 %arg) {
+entry:
+ switch i3 %arg, label %Default [
+ i3 -2, label %Label6
+ i3 1, label %Label1
+ i3 2, label %Label2
+ i3 3, label %Label3
+ i3 -4, label %Label4
+ i3 -3, label %Label5
+ ]
+
+Default:
+ %v1 = phi i64 [ 7, %Label6 ], [ 11, %Label5 ], [ 6, %Label4 ], [ 13, %Label3 ], [ 9, %Label2 ], [ 15, %Label1 ], [ 8, %entry ]
+ %v2 = phi i64 [ 0, %Label6 ], [ 0, %Label5 ], [ 0, %Label4 ], [ 0, %Label3 ], [ 0, %Label2 ], [ 0, %Label1 ], [ 0, %entry ]
+ %v3 = add i64 %v1, %v2
+ ret i64 %v3
+
+Label1:
+ br label %Default
+
+Label2:
+ br label %Default
+
+Label3:
+ br label %Default
+
+Label4:
+ br label %Default
+
+Label5:
+ br label %Default
+
+Label6:
+ br label %Default
+}
diff --git a/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll b/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll
new file mode 100644
index 0000000..d0b8ab2
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll
@@ -0,0 +1,41 @@
+; RUN: opt -S -simplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
+; rdar://17735071
+target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin12.0.0"
+
+; When tableindex can't fit into i2, we should extend the type to i3.
+; CHECK-LABEL: @_TFO6reduce1E5toRawfS0_FT_Si
+; CHECK: entry:
+; CHECK-NEXT: sub i2 %0, -2
+; CHECK-NEXT: zext i2 %switch.tableidx to i3
+; CHECK-NEXT: getelementptr inbounds [4 x i64]* @switch.table, i32 0, i3 %switch.tableidx.zext
+; CHECK-NEXT: load i64* %switch.gep
+; CHECK-NEXT: ret i64 %switch.load
+define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) {
+entry:
+ switch i2 %0, label %1 [
+ i2 0, label %2
+ i2 1, label %3
+ i2 -2, label %4
+ i2 -1, label %5
+ ]
+
+; <label>:1 ; preds = %entry
+ unreachable
+
+; <label>:2 ; preds = %2
+ br label %6
+
+; <label>:3 ; preds = %4
+ br label %6
+
+; <label>:4 ; preds = %6
+ br label %6
+
+; <label>:5 ; preds = %8
+ br label %6
+
+; <label>:6 ; preds = %3, %5, %7, %9
+ %7 = phi i64 [ 3, %5 ], [ 2, %4 ], [ 1, %3 ], [ 0, %2 ]
+ ret i64 %7
+}
diff --git a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
index 51ced40..fc22e7e 100644
--- a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
+++ b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
@@ -856,10 +856,10 @@ return:
; CHECK: entry:
; CHECK: br i1 %{{.*}}, label %switch.hole_check, label %sw.default
; CHECK: switch.hole_check:
-; CHECK-NEXT: %switch.maskindex = trunc i32 %switch.tableidx to i6
-; CHECK-NEXT: %switch.shifted = lshr i6 -17, %switch.maskindex
+; CHECK-NEXT: %switch.maskindex = trunc i32 %switch.tableidx to i8
+; CHECK-NEXT: %switch.shifted = lshr i8 47, %switch.maskindex
; The mask is binary 101111.
-; CHECK-NEXT: %switch.lobit = trunc i6 %switch.shifted to i1
+; CHECK-NEXT: %switch.lobit = trunc i8 %switch.shifted to i1
; CHECK-NEXT: br i1 %switch.lobit, label %switch.lookup, label %sw.default
; CHECK-NOT: switch i32
}
@@ -895,7 +895,7 @@ sw.bb1: br label %return
sw.bb2: br label %return
sw.default: br label %return
return:
- %x = phi i32 [ 3, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 9, %entry ]
+ %x = phi i32 [ 3, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 10, %entry ]
ret i32 %x
; CHECK-LABEL: @threecases(
; CHECK-NOT: switch i32
@@ -915,8 +915,12 @@ return:
%x = phi i32 [ 3, %sw.default ], [ 7, %sw.bb1 ], [ 9, %entry ]
ret i32 %x
; CHECK-LABEL: @twocases(
-; CHECK: switch i32
+; CHECK-NOT: switch i32
; CHECK-NOT: @switch.table
+; CHECK: %switch.selectcmp
+; CHECK-NEXT: %switch.select
+; CHECK-NEXT: %switch.selectcmp1
+; CHECK-NEXT: %switch.select2
}
; Don't build tables for switches with TLS variables.
@@ -973,3 +977,104 @@ return:
; CHECK: switch i32
; CHECK-NOT: @switch.table
}
+
+; We can use linear mapping.
+define i8 @linearmap1(i32 %c) {
+entry:
+ switch i32 %c, label %sw.default [
+ i32 10, label %return
+ i32 11, label %sw.bb1
+ i32 12, label %sw.bb2
+ i32 13, label %sw.bb3
+ ]
+sw.bb1: br label %return
+sw.bb2: br label %return
+sw.bb3: br label %return
+sw.default: br label %return
+return:
+ %x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 8, %sw.bb2 ], [ 13, %sw.bb1 ], [ 18, %entry ]
+ ret i8 %x
+; CHECK-LABEL: @linearmap1(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %c, 10
+; CHECK: switch.lookup:
+; CHECK-NEXT: %switch.idx.cast = trunc i32 %switch.tableidx to i8
+; CHECK-NEXT: %switch.idx.mult = mul i8 %switch.idx.cast, -5
+; CHECK-NEXT: %switch.offset = add i8 %switch.idx.mult, 18
+; CHECK-NEXT: ret i8 %switch.offset
+}
+
+; Linear mapping in a different configuration.
+define i32 @linearmap2(i8 %c) {
+entry:
+ switch i8 %c, label %sw.default [
+ i8 -10, label %return
+ i8 -11, label %sw.bb1
+ i8 -12, label %sw.bb2
+ i8 -13, label %sw.bb3
+ ]
+sw.bb1: br label %return
+sw.bb2: br label %return
+sw.bb3: br label %return
+sw.default: br label %return
+return:
+ %x = phi i32 [ 3, %sw.default ], [ 18, %sw.bb3 ], [ 19, %sw.bb2 ], [ 20, %sw.bb1 ], [ 21, %entry ]
+ ret i32 %x
+; CHECK-LABEL: @linearmap2(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i8 %c, -13
+; CHECK: switch.lookup:
+; CHECK-NEXT: %switch.idx.cast = zext i8 %switch.tableidx to i32
+; CHECK-NEXT: %switch.offset = add i32 %switch.idx.cast, 18
+; CHECK-NEXT: ret i32 %switch.offset
+}
+
+; Linear mapping with overflows.
+define i8 @linearmap3(i32 %c) {
+entry:
+ switch i32 %c, label %sw.default [
+ i32 10, label %return
+ i32 11, label %sw.bb1
+ i32 12, label %sw.bb2
+ i32 13, label %sw.bb3
+ ]
+sw.bb1: br label %return
+sw.bb2: br label %return
+sw.bb3: br label %return
+sw.default: br label %return
+return:
+ %x = phi i8 [ 3, %sw.default ], [ 44, %sw.bb3 ], [ -56, %sw.bb2 ], [ 100, %sw.bb1 ], [ 0, %entry ]
+ ret i8 %x
+; CHECK-LABEL: @linearmap3(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %c, 10
+; CHECK: switch.lookup:
+; CHECK-NEXT: %switch.idx.cast = trunc i32 %switch.tableidx to i8
+; CHECK-NEXT: %switch.idx.mult = mul i8 %switch.idx.cast, 100
+; CHECK-NEXT: ret i8 %switch.idx.mult
+}
+
+; Linear mapping with with multiplier 1 and offset 0.
+define i8 @linearmap4(i32 %c) {
+entry:
+ switch i32 %c, label %sw.default [
+ i32 -2, label %return
+ i32 -1, label %sw.bb1
+ i32 0, label %sw.bb2
+ i32 1, label %sw.bb3
+ ]
+sw.bb1: br label %return
+sw.bb2: br label %return
+sw.bb3: br label %return
+sw.default: br label %return
+return:
+ %x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %entry ]
+ ret i8 %x
+; CHECK-LABEL: @linearmap4(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %c, -2
+; CHECK: switch.lookup:
+; CHECK-NEXT: %switch.idx.cast = trunc i32 %switch.tableidx to i8
+; CHECK-NEXT: ret i8 %switch.idx.cast
+}
+