1; RUN: opt -S -instcombine < %s | FileCheck %s 2 3declare 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 9define 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 19normal: 20 ret void 21unreached: 22 call void @use(i32 %result) 23 ret void 24} 25 26define 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 35normal: 36 ret void 37unreached: 38 call void @use(i32 %result) 39 ret void 40} 41 42define 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 51normal: 52 ret void 53unreached: 54 call void @use(i32 %result) 55 ret void 56} 57 58define 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 68normal: 69 ret void 70unreached: 71 call void @use(i32 %result) 72 ret void 73} 74 75define 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 85normal: 86 ret void 87unreached: 88 call void @use(i32 %result) 89 ret void 90} 91 92define 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 102normal: 103 ret void 104unreached: 105 call void @use(i32 %result) 106 ret void 107} 108 109define 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 119normal: 120 ret void 121unreached: 122 call void @use(i32 %result) 123 ret void 124} 125 126define 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 136normal: 137 ret void 138unreached: 139 call void @use(i32 %result) 140 ret void 141} 142 143define 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 153normal: 154 ret void 155unreached: 156 call void @use(i32 %result) 157 ret void 158} 159 160define 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 170normal: 171 ret void 172unreached: 173 call void @use(i32 %result) 174 ret void 175} 176 177define 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 187normal: 188 ret void 189unreached: 190 call void @use(i32 %result) 191 ret void 192} 193 194define 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 204normal: 205 ret void 206unreached: 207 call void @use(i32 %result) 208 ret void 209} 210 211define 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 220normal: 221 ret void 222unreached: 223 call void @use(i32 %result) 224 ret void 225} 226 227define 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 237normal: 238 ret void 239unreached: 240 call void @use(i32 %result) 241 ret void 242} 243 244define 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 254normal: 255 ret void 256unreached: 257 call void @use(i32 %result) 258 ret void 259} 260 261define 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 270normal: 271 ret void 272unreached: 273 call void @use(i32 %result) 274 ret void 275} 276 277define 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 287normal: 288 ret void 289unreached: 290 call void @use(i32 %result) 291 ret void 292} 293 294define 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 304normal: 305 ret void 306unreached: 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 314define 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 324normal: 325 ret void 326unreached: 327 call void @use(i32 %result) 328 ret void 329} 330 331define 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 341normal: 342 ret void 343unreached: 344 call void @use(i32 %result) 345 ret void 346} 347 348define 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 358normal: 359 ret void 360unreached: 361 call void @use(i32 %result) 362 ret void 363} 364 365define 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 374normal: 375 ret void 376unreached: 377 call void @use(i32 %result) 378 ret void 379} 380 381define 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 390normal: 391 ret void 392unreached: 393 call void @use(i32 %result) 394 ret void 395} 396