1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 2; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s 3 4declare void @use_i1(i1 %x) 5declare void @use_i32(i32 %x) 6 7; Based on the IR generated for the `last` method of the type `slice` in Rust 8define ptr @test_last_elem_from_ptr(ptr noundef readnone %x0, i64 noundef %x1) { 9; CHECK-LABEL: test_last_elem_from_ptr: 10; CHECK: // %bb.0: 11; CHECK-NEXT: subs x8, x1, #1 12; CHECK-NEXT: add x8, x8, x0 13; CHECK-NEXT: csel x0, xzr, x8, lo 14; CHECK-NEXT: ret 15 %cmp = icmp eq i64 %x1, 0 16 %add.ptr = getelementptr inbounds nuw i8, ptr %x0, i64 %x1 17 %add.ptr1 = getelementptr inbounds i8, ptr %add.ptr, i64 -1 18 %retval.0 = select i1 %cmp, ptr null, ptr %add.ptr1 19 ret ptr %retval.0 20} 21 22define i32 @test_eq0_sub_add_i32(i32 %x0, i32 %x1) { 23; CHECK-LABEL: test_eq0_sub_add_i32: 24; CHECK: // %bb.0: 25; CHECK-NEXT: subs w8, w1, #1 26; CHECK-NEXT: add w8, w8, w0 27; CHECK-NEXT: csel w0, wzr, w8, lo 28; CHECK-NEXT: ret 29 %cmp = icmp eq i32 %x1, 0 30 %add = add nuw i32 %x0, %x1 31 %sub = sub i32 %add, 1 32 %ret = select i1 %cmp, i32 0, i32 %sub 33 ret i32 %ret 34} 35 36define i32 @test_eq7_sub_add_i32(i32 %x0, i32 %x1) { 37; CHECK-LABEL: test_eq7_sub_add_i32: 38; CHECK: // %bb.0: 39; CHECK-NEXT: subs w8, w1, #7 40; CHECK-NEXT: add w8, w8, w0 41; CHECK-NEXT: csel w0, wzr, w8, eq 42; CHECK-NEXT: ret 43 %cmp = icmp eq i32 %x1, 7 44 %add = add nuw i32 %x0, %x1 45 %sub = sub i32 %add, 7 46 %ret = select i1 %cmp, i32 0, i32 %sub 47 ret i32 %ret 48} 49 50define i32 @test_ule7_sub7_add_i32(i32 %x0, i32 %x1) { 51; CHECK-LABEL: test_ule7_sub7_add_i32: 52; CHECK: // %bb.0: 53; CHECK-NEXT: subs w8, w1, #7 54; CHECK-NEXT: add w8, w8, w0 55; CHECK-NEXT: csel w0, wzr, w8, ls 56; CHECK-NEXT: ret 57 %cmp = icmp ule i32 %x1, 7 58 %add = add i32 %x0, %x1 59 %sub = sub i32 %add, 7 60 %ret = select i1 %cmp, i32 0, i32 %sub 61 ret i32 %ret 62} 63 64define i32 @test_ule7_sub8_add_i32(i32 %x0, i32 %x1) { 65; CHECK-LABEL: test_ule7_sub8_add_i32: 66; CHECK: // %bb.0: 67; CHECK-NEXT: subs w8, w1, #8 68; CHECK-NEXT: add w8, w8, w0 69; CHECK-NEXT: csel w0, wzr, w8, lo 70; CHECK-NEXT: ret 71 %cmp = icmp ule i32 %x1, 7 72 %add = add i32 %x0, %x1 73 %sub = sub i32 %add, 8 74 %ret = select i1 %cmp, i32 0, i32 %sub 75 ret i32 %ret 76} 77 78define i32 @test_ule0_sub1_add_i32(i32 %x0, i32 %x1) { 79; CHECK-LABEL: test_ule0_sub1_add_i32: 80; CHECK: // %bb.0: 81; CHECK-NEXT: subs w8, w1, #1 82; CHECK-NEXT: add w8, w8, w0 83; CHECK-NEXT: csel w0, wzr, w8, lo 84; CHECK-NEXT: ret 85 %cmp = icmp ule i32 %x1, 0 86 %add = add i32 %x0, %x1 87 %sub = sub i32 %add, 1 88 %ret = select i1 %cmp, i32 0, i32 %sub 89 ret i32 %ret 90} 91 92define i32 @test_ultminus2_subminus2_add_i32(i32 %x0, i32 %x1) { 93; CHECK-LABEL: test_ultminus2_subminus2_add_i32: 94; CHECK: // %bb.0: 95; CHECK-NEXT: adds w8, w1, #2 96; CHECK-NEXT: add w8, w8, w0 97; CHECK-NEXT: csel w0, wzr, w8, lo 98; CHECK-NEXT: ret 99 %cmp = icmp ult i32 %x1, -2 100 %add = add i32 %x0, %x1 101 %sub = sub i32 %add, -2 102 %ret = select i1 %cmp, i32 0, i32 %sub 103 ret i32 %ret 104} 105 106define i32 @test_ultminus2_subminus3_add_i32(i32 %x0, i32 %x1) { 107; CHECK-LABEL: test_ultminus2_subminus3_add_i32: 108; CHECK: // %bb.0: 109; CHECK-NEXT: adds w8, w1, #3 110; CHECK-NEXT: add w8, w8, w0 111; CHECK-NEXT: csel w0, wzr, w8, ls 112; CHECK-NEXT: ret 113 %cmp = icmp ult i32 %x1, -2 114 %add = add i32 %x0, %x1 115 %sub = sub i32 %add, -3 116 %ret = select i1 %cmp, i32 0, i32 %sub 117 ret i32 %ret 118} 119 120define i32 @test_ne0_sub_add_i32(i32 %x0, i32 %x1) { 121; CHECK-LABEL: test_ne0_sub_add_i32: 122; CHECK: // %bb.0: 123; CHECK-NEXT: subs w8, w1, #1 124; CHECK-NEXT: add w8, w8, w0 125; CHECK-NEXT: csel w0, w8, wzr, hs 126; CHECK-NEXT: ret 127 %cmp = icmp ne i32 %x1, 0 128 %add = add i32 %x0, %x1 129 %sub = sub i32 %add, 1 130 %ret = select i1 %cmp, i32 %sub, i32 0 131 ret i32 %ret 132} 133 134define i32 @test_ne7_sub_add_i32(i32 %x0, i32 %x1) { 135; CHECK-LABEL: test_ne7_sub_add_i32: 136; CHECK: // %bb.0: 137; CHECK-NEXT: subs w8, w1, #7 138; CHECK-NEXT: add w8, w8, w0 139; CHECK-NEXT: csel w0, w8, wzr, ne 140; CHECK-NEXT: ret 141 %cmp = icmp ne i32 %x1, 7 142 %add = add i32 %x0, %x1 143 %sub = sub i32 %add, 7 144 %ret = select i1 %cmp, i32 %sub, i32 0 145 ret i32 %ret 146} 147 148define i32 @test_ultminus1_sub_add_i32(i32 %x0, i32 %x1) { 149; CHECK-LABEL: test_ultminus1_sub_add_i32: 150; CHECK: // %bb.0: 151; CHECK-NEXT: adds w8, w1, #1 152; CHECK-NEXT: add w8, w8, w0 153; CHECK-NEXT: csel w0, wzr, w8, ne 154; CHECK-NEXT: ret 155 %cmp = icmp ult i32 %x1, -1 156 %add = add i32 %x0, %x1 157 %sub = sub i32 %add, -1 158 %ret = select i1 %cmp, i32 0, i32 %sub 159 ret i32 %ret 160} 161 162define i32 @test_ugt7_sub7_add_i32(i32 %x0, i32 %x1) { 163; CHECK-LABEL: test_ugt7_sub7_add_i32: 164; CHECK: // %bb.0: 165; CHECK-NEXT: subs w8, w1, #7 166; CHECK-NEXT: add w8, w8, w0 167; CHECK-NEXT: csel w0, wzr, w8, hi 168; CHECK-NEXT: ret 169 %cmp = icmp ugt i32 %x1, 7 170 %add = add i32 %x0, %x1 171 %sub = sub i32 %add, 7 172 %ret = select i1 %cmp, i32 0, i32 %sub 173 ret i32 %ret 174} 175 176define i32 @test_ugt7_sub8_add_i32(i32 %x0, i32 %x1) { 177; CHECK-LABEL: test_ugt7_sub8_add_i32: 178; CHECK: // %bb.0: 179; CHECK-NEXT: subs w8, w1, #8 180; CHECK-NEXT: add w8, w8, w0 181; CHECK-NEXT: csel w0, wzr, w8, hs 182; CHECK-NEXT: ret 183 %cmp = icmp ugt i32 %x1, 7 184 %add = add i32 %x0, %x1 185 %sub = sub i32 %add, 8 186 %ret = select i1 %cmp, i32 0, i32 %sub 187 ret i32 %ret 188} 189 190define i32 @test_sle7_sub7_add_i32(i32 %x0, i32 %x1) { 191; CHECK-LABEL: test_sle7_sub7_add_i32: 192; CHECK: // %bb.0: 193; CHECK-NEXT: subs w8, w1, #7 194; CHECK-NEXT: add w8, w8, w0 195; CHECK-NEXT: csel w0, wzr, w8, le 196; CHECK-NEXT: ret 197 %cmp = icmp sle i32 %x1, 7 198 %add = add i32 %x0, %x1 199 %sub = sub i32 %add, 7 200 %ret = select i1 %cmp, i32 0, i32 %sub 201 ret i32 %ret 202} 203 204define i32 @test_sle7_sub8_add_i32(i32 %x0, i32 %x1) { 205; CHECK-LABEL: test_sle7_sub8_add_i32: 206; CHECK: // %bb.0: 207; CHECK-NEXT: subs w8, w1, #8 208; CHECK-NEXT: add w8, w8, w0 209; CHECK-NEXT: csel w0, wzr, w8, lt 210; CHECK-NEXT: ret 211 %cmp = icmp sle i32 %x1, 7 212 %add = add i32 %x0, %x1 213 %sub = sub i32 %add, 8 214 %ret = select i1 %cmp, i32 0, i32 %sub 215 ret i32 %ret 216} 217 218define i32 @test_slt8_sub8_add_i32(i32 %x0, i32 %x1) { 219; CHECK-LABEL: test_slt8_sub8_add_i32: 220; CHECK: // %bb.0: 221; CHECK-NEXT: subs w8, w1, #8 222; CHECK-NEXT: add w8, w8, w0 223; CHECK-NEXT: csel w0, wzr, w8, lt 224; CHECK-NEXT: ret 225 %cmp = icmp slt i32 %x1, 8 226 %add = add i32 %x0, %x1 227 %sub = sub i32 %add, 8 228 %ret = select i1 %cmp, i32 0, i32 %sub 229 ret i32 %ret 230} 231 232define i32 @test_slt8_sub7_add_i32(i32 %x0, i32 %x1) { 233; CHECK-LABEL: test_slt8_sub7_add_i32: 234; CHECK: // %bb.0: 235; CHECK-NEXT: subs w8, w1, #7 236; CHECK-NEXT: add w8, w8, w0 237; CHECK-NEXT: csel w0, wzr, w8, le 238; CHECK-NEXT: ret 239 %cmp = icmp slt i32 %x1, 8 240 %add = add i32 %x0, %x1 241 %sub = sub i32 %add, 7 242 %ret = select i1 %cmp, i32 0, i32 %sub 243 ret i32 %ret 244} 245 246define i32 @test_sltminus8_subminus8_add_i32(i32 %x0, i32 %x1) { 247; CHECK-LABEL: test_sltminus8_subminus8_add_i32: 248; CHECK: // %bb.0: 249; CHECK-NEXT: adds w8, w1, #8 250; CHECK-NEXT: add w8, w8, w0 251; CHECK-NEXT: csel w0, wzr, w8, lt 252; CHECK-NEXT: ret 253 %cmp = icmp slt i32 %x1, -8 254 %add = add i32 %x0, %x1 255 %sub = sub i32 %add, -8 256 %ret = select i1 %cmp, i32 0, i32 %sub 257 ret i32 %ret 258} 259 260define i32 @test_sgtminus8_subminus8_add_i32(i32 %x0, i32 %x1) { 261; CHECK-LABEL: test_sgtminus8_subminus8_add_i32: 262; CHECK: // %bb.0: 263; CHECK-NEXT: adds w8, w1, #8 264; CHECK-NEXT: add w8, w8, w0 265; CHECK-NEXT: csel w0, wzr, w8, gt 266; CHECK-NEXT: ret 267 %cmp = icmp sgt i32 %x1, -8 268 %add = add i32 %x0, %x1 269 %sub = sub i32 %add, -8 270 %ret = select i1 %cmp, i32 0, i32 %sub 271 ret i32 %ret 272} 273 274define i32 @test_sgtminus8_subminus7_add_i32(i32 %x0, i32 %x1) { 275; CHECK-LABEL: test_sgtminus8_subminus7_add_i32: 276; CHECK: // %bb.0: 277; CHECK-NEXT: adds w8, w1, #7 278; CHECK-NEXT: add w8, w8, w0 279; CHECK-NEXT: csel w0, wzr, w8, ge 280; CHECK-NEXT: ret 281 %cmp = icmp sgt i32 %x1, -8 282 %add = add i32 %x0, %x1 283 %sub = sub i32 %add, -7 284 %ret = select i1 %cmp, i32 0, i32 %sub 285 ret i32 %ret 286} 287 288define i32 @test_eq0_sub_addcomm_i32(i32 %x0, i32 %x1) { 289; CHECK-LABEL: test_eq0_sub_addcomm_i32: 290; CHECK: // %bb.0: 291; CHECK-NEXT: subs w8, w1, #1 292; CHECK-NEXT: add w8, w8, w0 293; CHECK-NEXT: csel w0, wzr, w8, lo 294; CHECK-NEXT: ret 295 %cmp = icmp eq i32 %x1, 0 296 %add = add i32 %x1, %x0 297 %sub = sub i32 %add, 1 298 %ret = select i1 %cmp, i32 0, i32 %sub 299 ret i32 %ret 300} 301 302define i32 @test_eq0_subcomm_add_i32(i32 %x0, i32 %x1) { 303; CHECK-LABEL: test_eq0_subcomm_add_i32: 304; CHECK: // %bb.0: 305; CHECK-NEXT: subs w8, w1, #1 306; CHECK-NEXT: add w8, w8, w0 307; CHECK-NEXT: csel w0, wzr, w8, lo 308; CHECK-NEXT: ret 309 %cmp = icmp eq i32 %x1, 0 310 %add = add i32 %x0, %x1 311 %sub = add i32 -1, %add 312 %ret = select i1 %cmp, i32 0, i32 %sub 313 ret i32 %ret 314} 315 316define i32 @test_eq0_multi_use_sub_i32(i32 %x0, i32 %x1) { 317; CHECK-LABEL: test_eq0_multi_use_sub_i32: 318; CHECK: // %bb.0: 319; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 320; CHECK-NEXT: .cfi_def_cfa_offset 16 321; CHECK-NEXT: .cfi_offset w19, -8 322; CHECK-NEXT: .cfi_offset w30, -16 323; CHECK-NEXT: subs w8, w1, #1 324; CHECK-NEXT: add w0, w8, w0 325; CHECK-NEXT: csel w19, wzr, w0, lo 326; CHECK-NEXT: bl use_i32 327; CHECK-NEXT: mov w0, w19 328; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 329; CHECK-NEXT: ret 330 %cmp = icmp eq i32 %x1, 0 331 %add = add nuw i32 %x0, %x1 332 %sub = sub i32 %add, 1 333 tail call void @use_i32(i32 %sub) 334 %ret = select i1 %cmp, i32 0, i32 %sub 335 ret i32 %ret 336} 337 338define i32 @test_eq_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) { 339; CHECK-LABEL: test_eq_nonconst_sub_add_i32: 340; CHECK: // %bb.0: 341; CHECK-NEXT: subs w8, w1, w2 342; CHECK-NEXT: add w8, w8, w0 343; CHECK-NEXT: csel w0, wzr, w8, eq 344; CHECK-NEXT: ret 345 %cmp = icmp eq i32 %x1, %x2 346 %add = add nuw i32 %x0, %x1 347 %sub = sub i32 %add, %x2 348 %ret = select i1 %cmp, i32 0, i32 %sub 349 ret i32 %ret 350} 351 352define i32 @test_ne_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) { 353; CHECK-LABEL: test_ne_nonconst_sub_add_i32: 354; CHECK: // %bb.0: 355; CHECK-NEXT: subs w8, w1, w2 356; CHECK-NEXT: add w8, w8, w0 357; CHECK-NEXT: csel w0, wzr, w8, ne 358; CHECK-NEXT: ret 359 %cmp = icmp ne i32 %x1, %x2 360 %add = add nuw i32 %x0, %x1 361 %sub = sub i32 %add, %x2 362 %ret = select i1 %cmp, i32 0, i32 %sub 363 ret i32 %ret 364} 365 366define i32 @test_ult_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 367; CHECK-LABEL: test_ult_nonconst_i32: 368; CHECK: // %bb.0: 369; CHECK-NEXT: subs w8, w1, w2 370; CHECK-NEXT: add w8, w8, w0 371; CHECK-NEXT: csel w0, wzr, w8, lo 372; CHECK-NEXT: ret 373 %cmp = icmp ult i32 %x1, %x2 374 %add = add i32 %x0, %x1 375 %sub = sub i32 %add, %x2 376 %ret = select i1 %cmp, i32 0, i32 %sub 377 ret i32 %ret 378} 379 380define i32 @test_ule_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 381; CHECK-LABEL: test_ule_nonconst_i32: 382; CHECK: // %bb.0: 383; CHECK-NEXT: subs w8, w1, w2 384; CHECK-NEXT: add w8, w8, w0 385; CHECK-NEXT: csel w0, wzr, w8, ls 386; CHECK-NEXT: ret 387 %cmp = icmp ule i32 %x1, %x2 388 %add = add i32 %x0, %x1 389 %sub = sub i32 %add, %x2 390 %ret = select i1 %cmp, i32 0, i32 %sub 391 ret i32 %ret 392} 393 394define i32 @test_ugt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 395; CHECK-LABEL: test_ugt_nonconst_i32: 396; CHECK: // %bb.0: 397; CHECK-NEXT: subs w8, w1, w2 398; CHECK-NEXT: add w8, w8, w0 399; CHECK-NEXT: csel w0, wzr, w8, hi 400; CHECK-NEXT: ret 401 %cmp = icmp ugt i32 %x1, %x2 402 %add = add i32 %x0, %x1 403 %sub = sub i32 %add, %x2 404 %ret = select i1 %cmp, i32 0, i32 %sub 405 ret i32 %ret 406} 407 408define i32 @test_uge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 409; CHECK-LABEL: test_uge_nonconst_i32: 410; CHECK: // %bb.0: 411; CHECK-NEXT: subs w8, w1, w2 412; CHECK-NEXT: add w8, w8, w0 413; CHECK-NEXT: csel w0, wzr, w8, hs 414; CHECK-NEXT: ret 415 %cmp = icmp uge i32 %x1, %x2 416 %add = add i32 %x0, %x1 417 %sub = sub i32 %add, %x2 418 %ret = select i1 %cmp, i32 0, i32 %sub 419 ret i32 %ret 420} 421 422define i32 @test_slt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 423; CHECK-LABEL: test_slt_nonconst_i32: 424; CHECK: // %bb.0: 425; CHECK-NEXT: subs w8, w1, w2 426; CHECK-NEXT: add w8, w8, w0 427; CHECK-NEXT: csel w0, wzr, w8, lt 428; CHECK-NEXT: ret 429 %cmp = icmp slt i32 %x1, %x2 430 %add = add i32 %x0, %x1 431 %sub = sub i32 %add, %x2 432 %ret = select i1 %cmp, i32 0, i32 %sub 433 ret i32 %ret 434} 435 436define i32 @test_sle_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 437; CHECK-LABEL: test_sle_nonconst_i32: 438; CHECK: // %bb.0: 439; CHECK-NEXT: subs w8, w1, w2 440; CHECK-NEXT: add w8, w8, w0 441; CHECK-NEXT: csel w0, wzr, w8, le 442; CHECK-NEXT: ret 443 %cmp = icmp sle i32 %x1, %x2 444 %add = add i32 %x0, %x1 445 %sub = sub i32 %add, %x2 446 %ret = select i1 %cmp, i32 0, i32 %sub 447 ret i32 %ret 448} 449 450define i32 @test_sgt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 451; CHECK-LABEL: test_sgt_nonconst_i32: 452; CHECK: // %bb.0: 453; CHECK-NEXT: subs w8, w1, w2 454; CHECK-NEXT: add w8, w8, w0 455; CHECK-NEXT: csel w0, wzr, w8, gt 456; CHECK-NEXT: ret 457 %cmp = icmp sgt i32 %x1, %x2 458 %add = add i32 %x0, %x1 459 %sub = sub i32 %add, %x2 460 %ret = select i1 %cmp, i32 0, i32 %sub 461 ret i32 %ret 462} 463 464define i32 @test_sge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) { 465; CHECK-LABEL: test_sge_nonconst_i32: 466; CHECK: // %bb.0: 467; CHECK-NEXT: subs w8, w1, w2 468; CHECK-NEXT: add w8, w8, w0 469; CHECK-NEXT: csel w0, wzr, w8, ge 470; CHECK-NEXT: ret 471 %cmp = icmp sge i32 %x1, %x2 472 %add = add i32 %x0, %x1 473 %sub = sub i32 %add, %x2 474 %ret = select i1 %cmp, i32 0, i32 %sub 475 ret i32 %ret 476} 477 478define i64 @test_ult_nonconst_i64(i64 %x0, i64 %x1, i64 %x2) { 479; CHECK-LABEL: test_ult_nonconst_i64: 480; CHECK: // %bb.0: 481; CHECK-NEXT: subs x8, x1, x2 482; CHECK-NEXT: add x8, x8, x0 483; CHECK-NEXT: csel x0, xzr, x8, lo 484; CHECK-NEXT: ret 485 %cmp = icmp ult i64 %x1, %x2 486 %add = add i64 %x0, %x1 487 %sub = sub i64 %add, %x2 488 %ret = select i1 %cmp, i64 0, i64 %sub 489 ret i64 %ret 490} 491 492define i32 @test_eq_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 493; CHECK-LABEL: test_eq_nonconst_sub_add_comm_i32: 494; CHECK: // %bb.0: 495; CHECK-NEXT: subs w8, w1, w2 496; CHECK-NEXT: add w8, w8, w0 497; CHECK-NEXT: csel w0, wzr, w8, eq 498; CHECK-NEXT: ret 499 %cmp = icmp eq i32 %x2, %x1 500 %add = add nuw i32 %x0, %x1 501 %sub = sub i32 %add, %x2 502 %ret = select i1 %cmp, i32 0, i32 %sub 503 ret i32 %ret 504} 505 506define i32 @test_ne_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 507; CHECK-LABEL: test_ne_nonconst_sub_add_comm_i32: 508; CHECK: // %bb.0: 509; CHECK-NEXT: subs w8, w1, w2 510; CHECK-NEXT: add w8, w8, w0 511; CHECK-NEXT: csel w0, wzr, w8, ne 512; CHECK-NEXT: ret 513 %cmp = icmp ne i32 %x2, %x1 514 %add = add nuw i32 %x0, %x1 515 %sub = sub i32 %add, %x2 516 %ret = select i1 %cmp, i32 0, i32 %sub 517 ret i32 %ret 518} 519 520define i32 @test_ult_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 521; CHECK-LABEL: test_ult_nonconst_sub_add_comm_i32: 522; CHECK: // %bb.0: 523; CHECK-NEXT: subs w8, w1, w2 524; CHECK-NEXT: add w8, w8, w0 525; CHECK-NEXT: csel w0, wzr, w8, hi 526; CHECK-NEXT: ret 527 %cmp = icmp ult i32 %x2, %x1 528 %add = add nuw i32 %x0, %x1 529 %sub = sub i32 %add, %x2 530 %ret = select i1 %cmp, i32 0, i32 %sub 531 ret i32 %ret 532} 533 534define i32 @test_ule_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 535; CHECK-LABEL: test_ule_nonconst_sub_add_comm_i32: 536; CHECK: // %bb.0: 537; CHECK-NEXT: subs w8, w1, w2 538; CHECK-NEXT: add w8, w8, w0 539; CHECK-NEXT: csel w0, wzr, w8, hs 540; CHECK-NEXT: ret 541 %cmp = icmp ule i32 %x2, %x1 542 %add = add nuw i32 %x0, %x1 543 %sub = sub i32 %add, %x2 544 %ret = select i1 %cmp, i32 0, i32 %sub 545 ret i32 %ret 546} 547 548define i32 @test_ugt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 549; CHECK-LABEL: test_ugt_nonconst_sub_add_comm_i32: 550; CHECK: // %bb.0: 551; CHECK-NEXT: subs w8, w1, w2 552; CHECK-NEXT: add w8, w8, w0 553; CHECK-NEXT: csel w0, wzr, w8, lo 554; CHECK-NEXT: ret 555 %cmp = icmp ugt i32 %x2, %x1 556 %add = add nuw i32 %x0, %x1 557 %sub = sub i32 %add, %x2 558 %ret = select i1 %cmp, i32 0, i32 %sub 559 ret i32 %ret 560} 561 562define i32 @test_uge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 563; CHECK-LABEL: test_uge_nonconst_sub_add_comm_i32: 564; CHECK: // %bb.0: 565; CHECK-NEXT: subs w8, w1, w2 566; CHECK-NEXT: add w8, w8, w0 567; CHECK-NEXT: csel w0, wzr, w8, ls 568; CHECK-NEXT: ret 569 %cmp = icmp uge i32 %x2, %x1 570 %add = add nuw i32 %x0, %x1 571 %sub = sub i32 %add, %x2 572 %ret = select i1 %cmp, i32 0, i32 %sub 573 ret i32 %ret 574} 575 576define i32 @test_slt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 577; CHECK-LABEL: test_slt_nonconst_sub_add_comm_i32: 578; CHECK: // %bb.0: 579; CHECK-NEXT: subs w8, w1, w2 580; CHECK-NEXT: add w8, w8, w0 581; CHECK-NEXT: csel w0, wzr, w8, gt 582; CHECK-NEXT: ret 583 %cmp = icmp slt i32 %x2, %x1 584 %add = add nuw i32 %x0, %x1 585 %sub = sub i32 %add, %x2 586 %ret = select i1 %cmp, i32 0, i32 %sub 587 ret i32 %ret 588} 589 590define i32 @test_sle_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 591; CHECK-LABEL: test_sle_nonconst_sub_add_comm_i32: 592; CHECK: // %bb.0: 593; CHECK-NEXT: subs w8, w1, w2 594; CHECK-NEXT: add w8, w8, w0 595; CHECK-NEXT: csel w0, wzr, w8, ge 596; CHECK-NEXT: ret 597 %cmp = icmp sle i32 %x2, %x1 598 %add = add nuw i32 %x0, %x1 599 %sub = sub i32 %add, %x2 600 %ret = select i1 %cmp, i32 0, i32 %sub 601 ret i32 %ret 602} 603 604define i32 @test_sgt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 605; CHECK-LABEL: test_sgt_nonconst_sub_add_comm_i32: 606; CHECK: // %bb.0: 607; CHECK-NEXT: subs w8, w1, w2 608; CHECK-NEXT: add w8, w8, w0 609; CHECK-NEXT: csel w0, wzr, w8, lt 610; CHECK-NEXT: ret 611 %cmp = icmp sgt i32 %x2, %x1 612 %add = add nuw i32 %x0, %x1 613 %sub = sub i32 %add, %x2 614 %ret = select i1 %cmp, i32 0, i32 %sub 615 ret i32 %ret 616} 617 618define i32 @test_sge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) { 619; CHECK-LABEL: test_sge_nonconst_sub_add_comm_i32: 620; CHECK: // %bb.0: 621; CHECK-NEXT: subs w8, w1, w2 622; CHECK-NEXT: add w8, w8, w0 623; CHECK-NEXT: csel w0, wzr, w8, le 624; CHECK-NEXT: ret 625 %cmp = icmp sge i32 %x2, %x1 626 %add = add nuw i32 %x0, %x1 627 %sub = sub i32 %add, %x2 628 %ret = select i1 %cmp, i32 0, i32 %sub 629 ret i32 %ret 630} 631 632; Negative test 633define i32 @test_eq0_multi_use_cmp_i32(i32 %x0, i32 %x1) { 634; CHECK-LABEL: test_eq0_multi_use_cmp_i32: 635; CHECK: // %bb.0: 636; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 637; CHECK-NEXT: .cfi_def_cfa_offset 16 638; CHECK-NEXT: .cfi_offset w19, -8 639; CHECK-NEXT: .cfi_offset w30, -16 640; CHECK-NEXT: add w8, w0, w1 641; CHECK-NEXT: cmp w1, #0 642; CHECK-NEXT: sub w8, w8, #1 643; CHECK-NEXT: cset w0, eq 644; CHECK-NEXT: csel w19, wzr, w8, eq 645; CHECK-NEXT: bl use_i1 646; CHECK-NEXT: mov w0, w19 647; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 648; CHECK-NEXT: ret 649 %cmp = icmp eq i32 %x1, 0 650 tail call void @use_i1(i1 %cmp) 651 %add = add nuw i32 %x0, %x1 652 %sub = sub i32 %add, 1 653 %ret = select i1 %cmp, i32 0, i32 %sub 654 ret i32 %ret 655} 656 657; Negative test 658define i32 @test_eq0_multi_use_add_i32(i32 %x0, i32 %x1) { 659; CHECK-LABEL: test_eq0_multi_use_add_i32: 660; CHECK: // %bb.0: 661; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 662; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 663; CHECK-NEXT: .cfi_def_cfa_offset 32 664; CHECK-NEXT: .cfi_offset w19, -8 665; CHECK-NEXT: .cfi_offset w20, -16 666; CHECK-NEXT: .cfi_offset w30, -32 667; CHECK-NEXT: add w20, w0, w1 668; CHECK-NEXT: mov w19, w1 669; CHECK-NEXT: mov w0, w20 670; CHECK-NEXT: bl use_i32 671; CHECK-NEXT: sub w8, w20, #1 672; CHECK-NEXT: cmp w19, #0 673; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 674; CHECK-NEXT: csel w0, wzr, w8, eq 675; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 676; CHECK-NEXT: ret 677 %cmp = icmp eq i32 %x1, 0 678 %add = add nuw i32 %x0, %x1 679 tail call void @use_i32(i32 %add) 680 %sub = sub i32 %add, 1 681 %ret = select i1 %cmp, i32 0, i32 %sub 682 ret i32 %ret 683} 684 685; Negative test 686define i32 @test_eq1_sub_add_i32(i32 %x0, i32 %x1) { 687; CHECK-LABEL: test_eq1_sub_add_i32: 688; CHECK: // %bb.0: 689; CHECK-NEXT: add w8, w0, w1 690; CHECK-NEXT: cmp w1, #1 691; CHECK-NEXT: sub w8, w8, #2 692; CHECK-NEXT: csel w0, wzr, w8, eq 693; CHECK-NEXT: ret 694 %cmp = icmp eq i32 %x1, 1 695 %add = add i32 %x0, %x1 696 %sub = sub i32 %add, 2 697 %ret = select i1 %cmp, i32 0, i32 %sub 698 ret i32 %ret 699} 700 701; Negative test 702define i32 @test_ugtsmax_sub_add_i32(i32 %x0, i32 %x1) { 703; CHECK-LABEL: test_ugtsmax_sub_add_i32: 704; CHECK: // %bb.0: 705; CHECK-NEXT: mov w8, #-2147483648 // =0x80000000 706; CHECK-NEXT: add w9, w0, w1 707; CHECK-NEXT: cmp w1, #0 708; CHECK-NEXT: add w8, w9, w8 709; CHECK-NEXT: csel w0, wzr, w8, lt 710; CHECK-NEXT: ret 711 %cmp = icmp ugt i32 %x1, 2147483647 712 %add = add i32 %x0, %x1 713 %sub = sub i32 %add, 2147483648 714 %ret = select i1 %cmp, i32 0, i32 %sub 715 ret i32 %ret 716} 717 718; Negative test 719define i32 @test_eq_const_mismatch_i32(i32 %x0, i32 %x1) { 720; CHECK-LABEL: test_eq_const_mismatch_i32: 721; CHECK: // %bb.0: 722; CHECK-NEXT: add w8, w0, w1 723; CHECK-NEXT: cmp w1, #0 724; CHECK-NEXT: sub w8, w8, #2 725; CHECK-NEXT: csel w0, wzr, w8, eq 726; CHECK-NEXT: ret 727 %cmp = icmp eq i32 %x1, 0 728 %add = add i32 %x0, %x1 729 %sub = sub i32 %add, 2 730 %ret = select i1 %cmp, i32 0, i32 %sub 731 ret i32 %ret 732} 733 734; Negative test 735define i32 @test_ne_const_mismatch_i32(i32 %x0, i32 %x1) { 736; CHECK-LABEL: test_ne_const_mismatch_i32: 737; CHECK: // %bb.0: 738; CHECK-NEXT: add w8, w0, w1 739; CHECK-NEXT: cmp w1, #0 740; CHECK-NEXT: sub w8, w8, #2 741; CHECK-NEXT: csel w0, w8, wzr, ne 742; CHECK-NEXT: ret 743 %cmp = icmp ne i32 %x1, 0 744 %add = add i32 %x0, %x1 745 %sub = sub i32 %add, 2 746 %ret = select i1 %cmp, i32 %sub, i32 0 747 ret i32 %ret 748} 749 750; Negative test 751define i32 @test_ult7_const_mismatch_i32(i32 %x0, i32 %x1) { 752; CHECK-LABEL: test_ult7_const_mismatch_i32: 753; CHECK: // %bb.0: 754; CHECK-NEXT: add w8, w0, w1 755; CHECK-NEXT: cmp w1, #7 756; CHECK-NEXT: sub w8, w8, #8 757; CHECK-NEXT: csel w0, wzr, w8, lo 758; CHECK-NEXT: ret 759 %cmp = icmp ult i32 %x1, 7 760 %add = add i32 %x0, %x1 761 %sub = sub i32 %add, 8 762 %ret = select i1 %cmp, i32 0, i32 %sub 763 ret i32 %ret 764} 765 766; Negative test 767define i32 @test_ule7_const_mismatch_i32(i32 %x0, i32 %x1) { 768; CHECK-LABEL: test_ule7_const_mismatch_i32: 769; CHECK: // %bb.0: 770; CHECK-NEXT: add w8, w0, w1 771; CHECK-NEXT: cmp w1, #8 772; CHECK-NEXT: sub w8, w8, #6 773; CHECK-NEXT: csel w0, wzr, w8, lo 774; CHECK-NEXT: ret 775 %cmp = icmp ule i32 %x1, 7 776 %add = add i32 %x0, %x1 777 %sub = sub i32 %add, 6 778 %ret = select i1 %cmp, i32 0, i32 %sub 779 ret i32 %ret 780} 781 782; Negative test 783define i32 @test_ugt7_const_mismatch_i32(i32 %x0, i32 %x1) { 784; CHECK-LABEL: test_ugt7_const_mismatch_i32: 785; CHECK: // %bb.0: 786; CHECK-NEXT: add w8, w0, w1 787; CHECK-NEXT: cmp w1, #7 788; CHECK-NEXT: sub w8, w8, #6 789; CHECK-NEXT: csel w0, wzr, w8, hi 790; CHECK-NEXT: ret 791 %cmp = icmp ugt i32 %x1, 7 792 %add = add i32 %x0, %x1 793 %sub = sub i32 %add, 6 794 %ret = select i1 %cmp, i32 0, i32 %sub 795 ret i32 %ret 796} 797 798; Negative test 799define i32 @test_uge7_const_mismatch_i32(i32 %x0, i32 %x1) { 800; CHECK-LABEL: test_uge7_const_mismatch_i32: 801; CHECK: // %bb.0: 802; CHECK-NEXT: add w8, w0, w1 803; CHECK-NEXT: cmp w1, #6 804; CHECK-NEXT: sub w8, w8, #8 805; CHECK-NEXT: csel w0, wzr, w8, hi 806; CHECK-NEXT: ret 807 %cmp = icmp uge i32 %x1, 7 808 %add = add i32 %x0, %x1 809 %sub = sub i32 %add, 8 810 %ret = select i1 %cmp, i32 0, i32 %sub 811 ret i32 %ret 812} 813 814; Negative test 815define i32 @test_slt7_const_mismatch_i32(i32 %x0, i32 %x1) { 816; CHECK-LABEL: test_slt7_const_mismatch_i32: 817; CHECK: // %bb.0: 818; CHECK-NEXT: add w8, w0, w1 819; CHECK-NEXT: cmp w1, #7 820; CHECK-NEXT: sub w8, w8, #8 821; CHECK-NEXT: csel w0, wzr, w8, lt 822; CHECK-NEXT: ret 823 %cmp = icmp slt i32 %x1, 7 824 %add = add i32 %x0, %x1 825 %sub = sub i32 %add, 8 826 %ret = select i1 %cmp, i32 0, i32 %sub 827 ret i32 %ret 828} 829 830; Negative test 831define i32 @test_sle7_const_mismatch_i32(i32 %x0, i32 %x1) { 832; CHECK-LABEL: test_sle7_const_mismatch_i32: 833; CHECK: // %bb.0: 834; CHECK-NEXT: add w8, w0, w1 835; CHECK-NEXT: cmp w1, #8 836; CHECK-NEXT: sub w8, w8, #6 837; CHECK-NEXT: csel w0, wzr, w8, lt 838; CHECK-NEXT: ret 839 %cmp = icmp sle i32 %x1, 7 840 %add = add i32 %x0, %x1 841 %sub = sub i32 %add, 6 842 %ret = select i1 %cmp, i32 0, i32 %sub 843 ret i32 %ret 844} 845 846; Negative test 847define i32 @test_sgt7_const_mismatch_i32(i32 %x0, i32 %x1) { 848; CHECK-LABEL: test_sgt7_const_mismatch_i32: 849; CHECK: // %bb.0: 850; CHECK-NEXT: add w8, w0, w1 851; CHECK-NEXT: cmp w1, #7 852; CHECK-NEXT: sub w8, w8, #6 853; CHECK-NEXT: csel w0, wzr, w8, gt 854; CHECK-NEXT: ret 855 %cmp = icmp sgt i32 %x1, 7 856 %add = add i32 %x0, %x1 857 %sub = sub i32 %add, 6 858 %ret = select i1 %cmp, i32 0, i32 %sub 859 ret i32 %ret 860} 861 862; Negative test 863define i32 @test_sge7_const_mismatch_i32(i32 %x0, i32 %x1) { 864; CHECK-LABEL: test_sge7_const_mismatch_i32: 865; CHECK: // %bb.0: 866; CHECK-NEXT: add w8, w0, w1 867; CHECK-NEXT: cmp w1, #6 868; CHECK-NEXT: sub w8, w8, #8 869; CHECK-NEXT: csel w0, wzr, w8, gt 870; CHECK-NEXT: ret 871 %cmp = icmp sge i32 %x1, 7 872 %add = add i32 %x0, %x1 873 %sub = sub i32 %add, 8 874 %ret = select i1 %cmp, i32 0, i32 %sub 875 ret i32 %ret 876} 877 878; Negative test 879define i32 @test_unrelated_add_i32(i32 %x0, i32 %x1, i32 %x2) { 880; CHECK-LABEL: test_unrelated_add_i32: 881; CHECK: // %bb.0: 882; CHECK-NEXT: add w8, w0, w2 883; CHECK-NEXT: cmp w1, #0 884; CHECK-NEXT: sub w8, w8, #1 885; CHECK-NEXT: csel w0, wzr, w8, eq 886; CHECK-NEXT: ret 887 %cmp = icmp eq i32 %x1, 0 888 %add = add nuw i32 %x0, %x2 889 %sub = sub i32 %add, 1 890 %ret = select i1 %cmp, i32 0, i32 %sub 891 ret i32 %ret 892} 893 894; Negative test 895define i16 @test_eq0_sub_add_i16(i16 %x0, i16 %x1) { 896; CHECK-LABEL: test_eq0_sub_add_i16: 897; CHECK: // %bb.0: 898; CHECK-NEXT: add w8, w0, w1 899; CHECK-NEXT: tst w1, #0xffff 900; CHECK-NEXT: sub w8, w8, #1 901; CHECK-NEXT: csel w0, wzr, w8, eq 902; CHECK-NEXT: ret 903 %cmp = icmp eq i16 %x1, 0 904 %add = add nuw i16 %x0, %x1 905 %sub = sub i16 %add, 1 906 %ret = select i1 %cmp, i16 0, i16 %sub 907 ret i16 %ret 908} 909 910; Negative test 911define i8 @test_eq_nonconst_sub_add_i8(i8 %x0, i8 %x1, i8 %x2) { 912; CHECK-LABEL: test_eq_nonconst_sub_add_i8: 913; CHECK: // %bb.0: 914; CHECK-NEXT: and w8, w1, #0xff 915; CHECK-NEXT: add w9, w0, w1 916; CHECK-NEXT: sub w9, w9, w2 917; CHECK-NEXT: cmp w8, w2, uxtb 918; CHECK-NEXT: csel w0, wzr, w9, eq 919; CHECK-NEXT: ret 920 %cmp = icmp eq i8 %x1, %x2 921 %add = add nuw i8 %x0, %x1 922 %sub = sub i8 %add, %x2 923 %ret = select i1 %cmp, i8 0, i8 %sub 924 ret i8 %ret 925} 926 927; Negative test 928define i16 @test_eq_nonconst_sub_add_i16(i16 %x0, i16 %x1, i16 %x2) { 929; CHECK-LABEL: test_eq_nonconst_sub_add_i16: 930; CHECK: // %bb.0: 931; CHECK-NEXT: and w8, w1, #0xffff 932; CHECK-NEXT: add w9, w0, w1 933; CHECK-NEXT: sub w9, w9, w2 934; CHECK-NEXT: cmp w8, w2, uxth 935; CHECK-NEXT: csel w0, wzr, w9, eq 936; CHECK-NEXT: ret 937 %cmp = icmp eq i16 %x1, %x2 938 %add = add nuw i16 %x0, %x1 939 %sub = sub i16 %add, %x2 940 %ret = select i1 %cmp, i16 0, i16 %sub 941 ret i16 %ret 942} 943 944; Negative test 945define i32 @test_ule_unsigned_overflow(i32 %x0, i32 %x1) { 946; CHECK-LABEL: test_ule_unsigned_overflow: 947; CHECK: // %bb.0: 948; CHECK-NEXT: mov w0, wzr 949; CHECK-NEXT: ret 950 %cmp = icmp ule i32 %x1, -1 951 %add = add i32 %x0, %x1 952 %sub = sub i32 %add, 0 953 %ret = select i1 %cmp, i32 0, i32 %sub 954 ret i32 %ret 955} 956 957; Negative test 958define i32 @test_ugt_unsigned_overflow(i32 %x0, i32 %x1) { 959; CHECK-LABEL: test_ugt_unsigned_overflow: 960; CHECK: // %bb.0: 961; CHECK-NEXT: add w0, w0, w1 962; CHECK-NEXT: ret 963 %cmp = icmp ugt i32 %x1, -1 964 %add = add i32 %x0, %x1 965 %sub = sub i32 %add, 0 966 %ret = select i1 %cmp, i32 0, i32 %sub 967 ret i32 %ret 968} 969 970; Negative test 971define i32 @test_ult_unsigned_overflow(i32 %x0, i32 %x1) { 972; CHECK-LABEL: test_ult_unsigned_overflow: 973; CHECK: // %bb.0: 974; CHECK-NEXT: add w8, w0, w1 975; CHECK-NEXT: add w0, w8, #1 976; CHECK-NEXT: ret 977 %cmp = icmp ult i32 %x1, 0 978 %add = add i32 %x0, %x1 979 %sub = sub i32 %add, -1 980 %ret = select i1 %cmp, i32 0, i32 %sub 981 ret i32 %ret 982} 983 984; Negative test 985define i32 @test_uge_unsigned_overflow(i32 %x0, i32 %x1) { 986; CHECK-LABEL: test_uge_unsigned_overflow: 987; CHECK: // %bb.0: 988; CHECK-NEXT: mov w0, wzr 989; CHECK-NEXT: ret 990 %cmp = icmp uge i32 %x1, 0 991 %add = add i32 %x0, %x1 992 %sub = sub i32 %add, -1 993 %ret = select i1 %cmp, i32 0, i32 %sub 994 ret i32 %ret 995} 996 997; Negative test 998define i32 @test_slt_signed_overflow(i32 %x0, i32 %x1) { 999; CHECK-LABEL: test_slt_signed_overflow: 1000; CHECK: // %bb.0: 1001; CHECK-NEXT: mov w8, #-2147483647 // =0x80000001 1002; CHECK-NEXT: add w9, w0, w1 1003; CHECK-NEXT: add w0, w9, w8 1004; CHECK-NEXT: ret 1005 %cmp = icmp slt i32 %x1, 2147483648 1006 %add = add i32 %x0, %x1 1007 %sub = sub i32 %add, 2147483647 1008 %ret = select i1 %cmp, i32 0, i32 %sub 1009 ret i32 %ret 1010} 1011 1012; Negative test 1013define i32 @test_sle_signed_overflow(i32 %x0, i32 %x1) { 1014; CHECK-LABEL: test_sle_signed_overflow: 1015; CHECK: // %bb.0: 1016; CHECK-NEXT: mov w0, wzr 1017; CHECK-NEXT: ret 1018 %cmp = icmp sle i32 %x1, 2147483647 1019 %add = add i32 %x0, %x1 1020 %sub = sub i32 %add, 2147483648 1021 %ret = select i1 %cmp, i32 0, i32 %sub 1022 ret i32 %ret 1023} 1024 1025; Negative test 1026define i32 @test_sgt_signed_overflow(i32 %x0, i32 %x1) { 1027; CHECK-LABEL: test_sgt_signed_overflow: 1028; CHECK: // %bb.0: 1029; CHECK-NEXT: mov w8, #-2147483648 // =0x80000000 1030; CHECK-NEXT: add w9, w0, w1 1031; CHECK-NEXT: add w0, w9, w8 1032; CHECK-NEXT: ret 1033 %cmp = icmp sgt i32 %x1, 2147483647 1034 %add = add i32 %x0, %x1 1035 %sub = sub i32 %add, 2147483648 1036 %ret = select i1 %cmp, i32 0, i32 %sub 1037 ret i32 %ret 1038} 1039 1040; Negative test 1041define i32 @test_sge_signed_overflow(i32 %x0, i32 %x1) { 1042; CHECK-LABEL: test_sge_signed_overflow: 1043; CHECK: // %bb.0: 1044; CHECK-NEXT: mov w0, wzr 1045; CHECK-NEXT: ret 1046 %cmp = icmp sge i32 %x1, 2147483648 1047 %add = add i32 %x0, %x1 1048 %sub = sub i32 %add, 2147483647 1049 %ret = select i1 %cmp, i32 0, i32 %sub 1050 ret i32 %ret 1051} 1052 1053; Negative test 1054define i32 @test_eq0_bitwidth_mismatch(i32 %x0, i32 %x1) { 1055; CHECK-LABEL: test_eq0_bitwidth_mismatch: 1056; CHECK: // %bb.0: 1057; CHECK-NEXT: add w8, w0, w1 1058; CHECK-NEXT: tst w1, #0xffff 1059; CHECK-NEXT: sub w8, w8, #1 1060; CHECK-NEXT: csel w0, wzr, w8, eq 1061; CHECK-NEXT: ret 1062 %x1t = trunc i32 %x1 to i16 1063 %cmp = icmp eq i16 %x1t, 0 1064 %add = add i32 %x0, %x1 1065 %sub = sub i32 %add, 1 1066 %ret = select i1 %cmp, i32 0, i32 %sub 1067 ret i32 %ret 1068} 1069 1070; Negative test 1071define i32 @test_eq0_bitwidth_mismatch_2(i32 %x0, i64 %x1) { 1072; CHECK-LABEL: test_eq0_bitwidth_mismatch_2: 1073; CHECK: // %bb.0: 1074; CHECK-NEXT: add w8, w0, w1 1075; CHECK-NEXT: cmp x1, #0 1076; CHECK-NEXT: sub w8, w8, #1 1077; CHECK-NEXT: csel w0, wzr, w8, eq 1078; CHECK-NEXT: ret 1079 %x1t = trunc i64 %x1 to i32 1080 %cmp = icmp eq i64 %x1, 0 1081 %add = add i32 %x0, %x1t 1082 %sub = sub i32 %add, 1 1083 %ret = select i1 %cmp, i32 0, i32 %sub 1084 ret i32 %ret 1085} 1086 1087; Negative test 1088define i32 @test_ult_nonconst_op_mismatch_i32(i32 %x0, i32 %x1, i32 %x2) { 1089; CHECK-LABEL: test_ult_nonconst_op_mismatch_i32: 1090; CHECK: // %bb.0: 1091; CHECK-NEXT: add w8, w0, w1 1092; CHECK-NEXT: cmp w1, w2 1093; CHECK-NEXT: add w8, w8, w2 1094; CHECK-NEXT: csel w0, wzr, w8, lo 1095; CHECK-NEXT: ret 1096 %cmp = icmp ult i32 %x1, %x2 1097 %add = add i32 %x0, %x1 1098 %sub = add i32 %add, %x2 1099 %ret = select i1 %cmp, i32 0, i32 %sub 1100 ret i32 %ret 1101} 1102 1103; Negative test 1104define i32 @test_ult_nonconst_unrelated_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 1105; CHECK-LABEL: test_ult_nonconst_unrelated_i32: 1106; CHECK: // %bb.0: 1107; CHECK-NEXT: add w8, w0, w1 1108; CHECK-NEXT: cmp w1, w2 1109; CHECK-NEXT: sub w8, w8, w3 1110; CHECK-NEXT: csel w0, wzr, w8, lo 1111; CHECK-NEXT: ret 1112 %cmp = icmp ult i32 %x1, %x2 1113 %add = add i32 %x0, %x1 1114 %sub = sub i32 %add, %x3 1115 %ret = select i1 %cmp, i32 0, i32 %sub 1116 ret i32 %ret 1117} 1118 1119; Negative test 1120define i32 @test_ult_nonconst_unrelated_2_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 1121; CHECK-LABEL: test_ult_nonconst_unrelated_2_i32: 1122; CHECK: // %bb.0: 1123; CHECK-NEXT: add w8, w0, w1 1124; CHECK-NEXT: cmp w2, w1 1125; CHECK-NEXT: sub w8, w8, w3 1126; CHECK-NEXT: csel w0, wzr, w8, lo 1127; CHECK-NEXT: ret 1128 %cmp = icmp ult i32 %x2, %x1 1129 %add = add i32 %x0, %x1 1130 %sub = sub i32 %add, %x3 1131 %ret = select i1 %cmp, i32 0, i32 %sub 1132 ret i32 %ret 1133} 1134