1 ; RUN: opt -S -instcombine < %s | FileCheck %s 2 3 declare void @use(i32) 4 5 ; These 18 exercise all combinations of signed comparison 6 ; for each of the three values produced by your typical 7 ; 3way compare function (-1, 0, 1) 8 9 define void @test_low_sgt(i64 %a, i64 %b) { 10 ; CHECK-LABEL: @test_low_sgt 11 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 12 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 13 %eq = icmp eq i64 %a, %b 14 %slt = icmp slt i64 %a, %b 15 %. = select i1 %slt, i32 -1, i32 1 16 %result = select i1 %eq, i32 0, i32 %. 17 %cmp = icmp sgt i32 %result, -1 18 br i1 %cmp, label %unreached, label %normal 19 normal: 20 ret void 21 unreached: 22 call void @use(i32 %result) 23 ret void 24 } 25 26 define void @test_low_slt(i64 %a, i64 %b) { 27 ; CHECK-LABEL: @test_low_slt 28 ; CHECK: br i1 false, label %unreached, label %normal 29 %eq = icmp eq i64 %a, %b 30 %slt = icmp slt i64 %a, %b 31 %. = select i1 %slt, i32 -1, i32 1 32 %result = select i1 %eq, i32 0, i32 %. 33 %cmp = icmp slt i32 %result, -1 34 br i1 %cmp, label %unreached, label %normal 35 normal: 36 ret void 37 unreached: 38 call void @use(i32 %result) 39 ret void 40 } 41 42 define void @test_low_sge(i64 %a, i64 %b) { 43 ; CHECK-LABEL: @test_low_sge 44 ; CHECK: br i1 true, label %unreached, label %normal 45 %eq = icmp eq i64 %a, %b 46 %slt = icmp slt i64 %a, %b 47 %. = select i1 %slt, i32 -1, i32 1 48 %result = select i1 %eq, i32 0, i32 %. 49 %cmp = icmp sge i32 %result, -1 50 br i1 %cmp, label %unreached, label %normal 51 normal: 52 ret void 53 unreached: 54 call void @use(i32 %result) 55 ret void 56 } 57 58 define void @test_low_sle(i64 %a, i64 %b) { 59 ; CHECK-LABEL: @test_low_sle 60 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 61 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 62 %eq = icmp eq i64 %a, %b 63 %slt = icmp slt i64 %a, %b 64 %. = select i1 %slt, i32 -1, i32 1 65 %result = select i1 %eq, i32 0, i32 %. 66 %cmp = icmp sle i32 %result, -1 67 br i1 %cmp, label %unreached, label %normal 68 normal: 69 ret void 70 unreached: 71 call void @use(i32 %result) 72 ret void 73 } 74 75 define void @test_low_ne(i64 %a, i64 %b) { 76 ; CHECK-LABEL: @test_low_ne 77 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 78 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 79 %eq = icmp eq i64 %a, %b 80 %slt = icmp slt i64 %a, %b 81 %. = select i1 %slt, i32 -1, i32 1 82 %result = select i1 %eq, i32 0, i32 %. 83 %cmp = icmp ne i32 %result, -1 84 br i1 %cmp, label %unreached, label %normal 85 normal: 86 ret void 87 unreached: 88 call void @use(i32 %result) 89 ret void 90 } 91 92 define void @test_low_eq(i64 %a, i64 %b) { 93 ; CHECK-LABEL: @test_low_eq 94 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 95 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 96 %eq = icmp eq i64 %a, %b 97 %slt = icmp slt i64 %a, %b 98 %. = select i1 %slt, i32 -1, i32 1 99 %result = select i1 %eq, i32 0, i32 %. 100 %cmp = icmp eq i32 %result, -1 101 br i1 %cmp, label %unreached, label %normal 102 normal: 103 ret void 104 unreached: 105 call void @use(i32 %result) 106 ret void 107 } 108 109 define void @test_mid_sgt(i64 %a, i64 %b) { 110 ; CHECK-LABEL: @test_mid_sgt 111 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 112 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 113 %eq = icmp eq i64 %a, %b 114 %slt = icmp slt i64 %a, %b 115 %. = select i1 %slt, i32 -1, i32 1 116 %result = select i1 %eq, i32 0, i32 %. 117 %cmp = icmp sgt i32 %result, 0 118 br i1 %cmp, label %unreached, label %normal 119 normal: 120 ret void 121 unreached: 122 call void @use(i32 %result) 123 ret void 124 } 125 126 define void @test_mid_slt(i64 %a, i64 %b) { 127 ; CHECK-LABEL: @test_mid_slt 128 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 129 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 130 %eq = icmp eq i64 %a, %b 131 %slt = icmp slt i64 %a, %b 132 %. = select i1 %slt, i32 -1, i32 1 133 %result = select i1 %eq, i32 0, i32 %. 134 %cmp = icmp slt i32 %result, 0 135 br i1 %cmp, label %unreached, label %normal 136 normal: 137 ret void 138 unreached: 139 call void @use(i32 %result) 140 ret void 141 } 142 143 define void @test_mid_sge(i64 %a, i64 %b) { 144 ; CHECK-LABEL: @test_mid_sge 145 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 146 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 147 %eq = icmp eq i64 %a, %b 148 %slt = icmp slt i64 %a, %b 149 %. = select i1 %slt, i32 -1, i32 1 150 %result = select i1 %eq, i32 0, i32 %. 151 %cmp = icmp sge i32 %result, 0 152 br i1 %cmp, label %unreached, label %normal 153 normal: 154 ret void 155 unreached: 156 call void @use(i32 %result) 157 ret void 158 } 159 160 define void @test_mid_sle(i64 %a, i64 %b) { 161 ; CHECK-LABEL: @test_mid_sle 162 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 163 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 164 %eq = icmp eq i64 %a, %b 165 %slt = icmp slt i64 %a, %b 166 %. = select i1 %slt, i32 -1, i32 1 167 %result = select i1 %eq, i32 0, i32 %. 168 %cmp = icmp sle i32 %result, 0 169 br i1 %cmp, label %unreached, label %normal 170 normal: 171 ret void 172 unreached: 173 call void @use(i32 %result) 174 ret void 175 } 176 177 define void @test_mid_ne(i64 %a, i64 %b) { 178 ; CHECK-LABEL: @test_mid_ne 179 ; CHECK: [[TMP1:%.*]] = icmp eq i64 %a, %b 180 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 181 %eq = icmp eq i64 %a, %b 182 %slt = icmp slt i64 %a, %b 183 %. = select i1 %slt, i32 -1, i32 1 184 %result = select i1 %eq, i32 0, i32 %. 185 %cmp = icmp ne i32 %result, 0 186 br i1 %cmp, label %unreached, label %normal 187 normal: 188 ret void 189 unreached: 190 call void @use(i32 %result) 191 ret void 192 } 193 194 define void @test_mid_eq(i64 %a, i64 %b) { 195 ; CHECK-LABEL: @test_mid_eq 196 ; CHECK: icmp eq i64 %a, %b 197 ; CHECK: br i1 %eq, label %unreached, label %normal 198 %eq = icmp eq i64 %a, %b 199 %slt = icmp slt i64 %a, %b 200 %. = select i1 %slt, i32 -1, i32 1 201 %result = select i1 %eq, i32 0, i32 %. 202 %cmp = icmp eq i32 %result, 0 203 br i1 %cmp, label %unreached, label %normal 204 normal: 205 ret void 206 unreached: 207 call void @use(i32 %result) 208 ret void 209 } 210 211 define void @test_high_sgt(i64 %a, i64 %b) { 212 ; CHECK-LABEL: @test_high_sgt 213 ; CHECK: br i1 false, label %unreached, label %normal 214 %eq = icmp eq i64 %a, %b 215 %slt = icmp slt i64 %a, %b 216 %. = select i1 %slt, i32 -1, i32 1 217 %result = select i1 %eq, i32 0, i32 %. 218 %cmp = icmp sgt i32 %result, 1 219 br i1 %cmp, label %unreached, label %normal 220 normal: 221 ret void 222 unreached: 223 call void @use(i32 %result) 224 ret void 225 } 226 227 define void @test_high_slt(i64 %a, i64 %b) { 228 ; CHECK-LABEL: @test_high_slt 229 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 230 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 231 %eq = icmp eq i64 %a, %b 232 %slt = icmp slt i64 %a, %b 233 %. = select i1 %slt, i32 -1, i32 1 234 %result = select i1 %eq, i32 0, i32 %. 235 %cmp = icmp slt i32 %result, 1 236 br i1 %cmp, label %unreached, label %normal 237 normal: 238 ret void 239 unreached: 240 call void @use(i32 %result) 241 ret void 242 } 243 244 define void @test_high_sge(i64 %a, i64 %b) { 245 ; CHECK-LABEL: @test_high_sge 246 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 247 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 248 %eq = icmp eq i64 %a, %b 249 %slt = icmp slt i64 %a, %b 250 %. = select i1 %slt, i32 -1, i32 1 251 %result = select i1 %eq, i32 0, i32 %. 252 %cmp = icmp sge i32 %result, 1 253 br i1 %cmp, label %unreached, label %normal 254 normal: 255 ret void 256 unreached: 257 call void @use(i32 %result) 258 ret void 259 } 260 261 define void @test_high_sle(i64 %a, i64 %b) { 262 ; CHECK-LABEL: @test_high_sle 263 ; CHECK: br i1 true, label %unreached, label %normal 264 %eq = icmp eq i64 %a, %b 265 %slt = icmp slt i64 %a, %b 266 %. = select i1 %slt, i32 -1, i32 1 267 %result = select i1 %eq, i32 0, i32 %. 268 %cmp = icmp sle i32 %result, 1 269 br i1 %cmp, label %unreached, label %normal 270 normal: 271 ret void 272 unreached: 273 call void @use(i32 %result) 274 ret void 275 } 276 277 define void @test_high_ne(i64 %a, i64 %b) { 278 ; CHECK-LABEL: @test_high_ne 279 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 280 ; CHECK: br i1 [[TMP1]], label %normal, label %unreached 281 %eq = icmp eq i64 %a, %b 282 %slt = icmp slt i64 %a, %b 283 %. = select i1 %slt, i32 -1, i32 1 284 %result = select i1 %eq, i32 0, i32 %. 285 %cmp = icmp ne i32 %result, 1 286 br i1 %cmp, label %unreached, label %normal 287 normal: 288 ret void 289 unreached: 290 call void @use(i32 %result) 291 ret void 292 } 293 294 define void @test_high_eq(i64 %a, i64 %b) { 295 ; CHECK-LABEL: @test_high_eq 296 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 297 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 298 %eq = icmp eq i64 %a, %b 299 %slt = icmp slt i64 %a, %b 300 %. = select i1 %slt, i32 -1, i32 1 301 %result = select i1 %eq, i32 0, i32 %. 302 %cmp = icmp eq i32 %result, 1 303 br i1 %cmp, label %unreached, label %normal 304 normal: 305 ret void 306 unreached: 307 call void @use(i32 %result) 308 ret void 309 } 310 311 ; These five make sure we didn't accidentally hard code one of the 312 ; produced values 313 314 define void @non_standard_low(i64 %a, i64 %b) { 315 ; CHECK-LABEL: @non_standard_low 316 ; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b 317 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 318 %eq = icmp eq i64 %a, %b 319 %slt = icmp slt i64 %a, %b 320 %. = select i1 %slt, i32 -3, i32 -1 321 %result = select i1 %eq, i32 -2, i32 %. 322 %cmp = icmp eq i32 %result, -3 323 br i1 %cmp, label %unreached, label %normal 324 normal: 325 ret void 326 unreached: 327 call void @use(i32 %result) 328 ret void 329 } 330 331 define void @non_standard_mid(i64 %a, i64 %b) { 332 ; CHECK-LABEL: @non_standard_mid 333 ; CHECK: icmp eq i64 %a, %b 334 ; CHECK: br i1 %eq, label %unreached, label %normal 335 %eq = icmp eq i64 %a, %b 336 %slt = icmp slt i64 %a, %b 337 %. = select i1 %slt, i32 -3, i32 -1 338 %result = select i1 %eq, i32 -2, i32 %. 339 %cmp = icmp eq i32 %result, -2 340 br i1 %cmp, label %unreached, label %normal 341 normal: 342 ret void 343 unreached: 344 call void @use(i32 %result) 345 ret void 346 } 347 348 define void @non_standard_high(i64 %a, i64 %b) { 349 ; CHECK-LABEL: @non_standard_high 350 ; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b 351 ; CHECK: br i1 [[TMP1]], label %unreached, label %normal 352 %eq = icmp eq i64 %a, %b 353 %slt = icmp slt i64 %a, %b 354 %. = select i1 %slt, i32 -3, i32 -1 355 %result = select i1 %eq, i32 -2, i32 %. 356 %cmp = icmp eq i32 %result, -1 357 br i1 %cmp, label %unreached, label %normal 358 normal: 359 ret void 360 unreached: 361 call void @use(i32 %result) 362 ret void 363 } 364 365 define void @non_standard_bound1(i64 %a, i64 %b) { 366 ; CHECK-LABEL: @non_standard_bound1 367 ; CHECK: br i1 false, label %unreached, label %normal 368 %eq = icmp eq i64 %a, %b 369 %slt = icmp slt i64 %a, %b 370 %. = select i1 %slt, i32 -3, i32 -1 371 %result = select i1 %eq, i32 -2, i32 %. 372 %cmp = icmp eq i32 %result, -20 373 br i1 %cmp, label %unreached, label %normal 374 normal: 375 ret void 376 unreached: 377 call void @use(i32 %result) 378 ret void 379 } 380 381 define void @non_standard_bound2(i64 %a, i64 %b) { 382 ; CHECK-LABEL: @non_standard_bound2 383 ; CHECK: br i1 false, label %unreached, label %normal 384 %eq = icmp eq i64 %a, %b 385 %slt = icmp slt i64 %a, %b 386 %. = select i1 %slt, i32 -3, i32 -1 387 %result = select i1 %eq, i32 -2, i32 %. 388 %cmp = icmp eq i32 %result, 0 389 br i1 %cmp, label %unreached, label %normal 390 normal: 391 ret void 392 unreached: 393 call void @use(i32 %result) 394 ret void 395 } 396