[TableGen] Fix validateOperandClass for non Phyical Reg (#118146)
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / RISCV / switch_to_lookup_table-rv64.ll
blob6c9450bb8998edce8251a11561cc142e828e6669
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
2 ; RUN: opt < %s -passes=simplifycfg -switch-to-lookup=true -keep-loops=false -S -mattr=+f | FileCheck %s
3 ; RUN: opt < %s -passes='simplifycfg<no-keep-loops;switch-to-lookup>' -S -mattr=+f | FileCheck %s
4 target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
5 target triple = "riscv64-unknown-elf"
7 ; A simple int-to-int selection switch.
8 ; It is dense enough to be replaced by table lookup.
9 ; The result is directly by a ret from an otherwise empty bb,
10 ; so we return early, directly from the lookup bb.
13 ; CHECK: @.str = private unnamed_addr constant [4 x i8] c"foo\00", align 1
14 ; CHECK: @.str1 = private unnamed_addr constant [4 x i8] c"bar\00", align 1
15 ; CHECK: @.str2 = private unnamed_addr constant [4 x i8] c"baz\00", align 1
16 ; CHECK: @.str3 = private unnamed_addr constant [4 x i8] c"qux\00", align 1
17 ; CHECK: @.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1
18 ; CHECK: @switch.table.f = private unnamed_addr constant [7 x i32] [i32 55, i32 123, i32 0, i32 -1, i32 27, i32 62, i32 1], align 4
19 ; CHECK: @switch.table.char = private unnamed_addr constant [9 x i8] c"7{\00\FF\1B>\01!T", align 1
20 ; CHECK: @switch.table.h = private unnamed_addr constant [4 x float] [float 0x40091EB860000000, float 0x3FF3BE76C0000000, float 0x4012449BA0000000, float 0x4001AE1480000000], align 4
21 ; CHECK: @switch.table.foostring = private unnamed_addr constant [4 x ptr] [ptr @.str, ptr @.str1, ptr @.str2, ptr @.str3], align 8
23 define i32 @f(i32 %c) {
24 ; CHECK-LABEL: @f(
25 ; CHECK-NEXT:  entry:
26 ; CHECK-NEXT:    [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42
27 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7
28 ; CHECK-NEXT:    br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
29 ; CHECK:       switch.lookup:
30 ; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.f, i32 0, i32 [[SWITCH_TABLEIDX]]
31 ; CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
32 ; CHECK-NEXT:    br label [[RETURN]]
33 ; CHECK:       return:
34 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
35 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
37 entry:
38   switch i32 %c, label %sw.default [
39   i32 42, label %return
40   i32 43, label %sw.bb1
41   i32 44, label %sw.bb2
42   i32 45, label %sw.bb3
43   i32 46, label %sw.bb4
44   i32 47, label %sw.bb5
45   i32 48, label %sw.bb6
46   ]
48 sw.bb1: br label %return
49 sw.bb2: br label %return
50 sw.bb3: br label %return
51 sw.bb4: br label %return
52 sw.bb5: br label %return
53 sw.bb6: br label %return
54 sw.default: br label %return
55 return:
56   %retval.0 = phi i32 [ 15, %sw.default ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
57   ret i32 %retval.0
61 ; Same thing, but with i8's
63 define i8 @char(i32 %c) {
64 ; CHECK-LABEL: @char(
65 ; CHECK-NEXT:  entry:
66 ; CHECK-NEXT:    [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42
67 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9
68 ; CHECK-NEXT:    br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
69 ; CHECK:       switch.lookup:
70 ; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], ptr @switch.table.char, i32 0, i32 [[SWITCH_TABLEIDX]]
71 ; CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load i8, ptr [[SWITCH_GEP]], align 1
72 ; CHECK-NEXT:    br label [[RETURN]]
73 ; CHECK:       return:
74 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i8 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
75 ; CHECK-NEXT:    ret i8 [[RETVAL_0]]
77 entry:
78   switch i32 %c, label %sw.default [
79   i32 42, label %return
80   i32 43, label %sw.bb1
81   i32 44, label %sw.bb2
82   i32 45, label %sw.bb3
83   i32 46, label %sw.bb4
84   i32 47, label %sw.bb5
85   i32 48, label %sw.bb6
86   i32 49, label %sw.bb7
87   i32 50, label %sw.bb8
88   ]
90 sw.bb1: br label %return
91 sw.bb2: br label %return
92 sw.bb3: br label %return
93 sw.bb4: br label %return
94 sw.bb5: br label %return
95 sw.bb6: br label %return
96 sw.bb7: br label %return
97 sw.bb8: br label %return
98 sw.default: br label %return
99 return:
100   %retval.0 = phi i8 [ 15, %sw.default ], [ 84, %sw.bb8 ], [ 33, %sw.bb7 ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
101   ret i8 %retval.0
105 ; A switch used to initialize two variables, an i8 and a float.
107 declare void @dummy(i8 signext, float)
108 define void @h(i32 %x) {
109 ; CHECK-LABEL: @h(
110 ; CHECK-NEXT:  entry:
111 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
112 ; CHECK-NEXT:    br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]]
113 ; CHECK:       switch.lookup:
114 ; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[X]], 8
115 ; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]]
116 ; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8
117 ; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i32 0, i32 [[X]]
118 ; CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load float, ptr [[SWITCH_GEP]], align 4
119 ; CHECK-NEXT:    br label [[SW_EPILOG]]
120 ; CHECK:       sw.epilog:
121 ; CHECK-NEXT:    [[A_0:%.*]] = phi i8 [ [[SWITCH_MASKED]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ]
122 ; CHECK-NEXT:    [[B_0:%.*]] = phi float [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 0x4023FAE140000000, [[ENTRY]] ]
123 ; CHECK-NEXT:    call void @dummy(i8 signext [[A_0]], float [[B_0]])
124 ; CHECK-NEXT:    ret void
126 entry:
127   switch i32 %x, label %sw.default [
128   i32 0, label %sw.epilog
129   i32 1, label %sw.bb1
130   i32 2, label %sw.bb2
131   i32 3, label %sw.bb3
132   ]
134 sw.bb1: br label %sw.epilog
135 sw.bb2: br label %sw.epilog
136 sw.bb3: br label %sw.epilog
137 sw.default: br label %sw.epilog
139 sw.epilog:
140   %a.0 = phi i8 [ 7, %sw.default ], [ 5, %sw.bb3 ], [ 88, %sw.bb2 ], [ 9, %sw.bb1 ], [ 42, %entry ]
141   %b.0 = phi float [ 0x4023FAE140000000, %sw.default ], [ 0x4001AE1480000000, %sw.bb3 ], [ 0x4012449BA0000000, %sw.bb2 ], [ 0x3FF3BE76C0000000, %sw.bb1 ], [ 0x40091EB860000000, %entry ]
142   call void @dummy(i8 signext %a.0, float %b.0)
143   ret void
148 ; Switch used to return a string.
150 @.str = private unnamed_addr constant [4 x i8] c"foo\00", align 1
151 @.str1 = private unnamed_addr constant [4 x i8] c"bar\00", align 1
152 @.str2 = private unnamed_addr constant [4 x i8] c"baz\00", align 1
153 @.str3 = private unnamed_addr constant [4 x i8] c"qux\00", align 1
154 @.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1
156 define ptr @foostring(i32 %x)  {
157 ; CHECK-LABEL: @foostring(
158 ; CHECK-NEXT:  entry:
159 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
160 ; CHECK-NEXT:    br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
161 ; CHECK:       switch.lookup:
162 ; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x ptr], ptr @switch.table.foostring, i32 0, i32 [[X]]
163 ; CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load ptr, ptr [[SWITCH_GEP]], align 8
164 ; CHECK-NEXT:    br label [[RETURN]]
165 ; CHECK:       return:
166 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ @.str4, [[ENTRY:%.*]] ]
167 ; CHECK-NEXT:    ret ptr [[RETVAL_0]]
169 entry:
170   switch i32 %x, label %sw.default [
171   i32 0, label %return
172   i32 1, label %sw.bb1
173   i32 2, label %sw.bb2
174   i32 3, label %sw.bb3
175   ]
177 sw.bb1: br label %return
178 sw.bb2: br label %return
179 sw.bb3: br label %return
180 sw.default: br label %return
182 return:
183   %retval.0 = phi ptr [ @.str4, %sw.default ],
184   [ @.str3, %sw.bb3 ],
185   [ @.str2, %sw.bb2 ],
186   [ @.str1, %sw.bb1 ],
187   [ @.str, %entry ]
188   ret ptr %retval.0
192 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { "target-features"="+f" }