1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -debugify-and-strip-all-safe -enable-machine-outliner=never -verify-machineinstrs %s -o - -mtriple=aarch64-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s 3; RUN: llc -debugify-and-strip-all-safe -global-isel -enable-machine-outliner=never -verify-machineinstrs %s -o - -mtriple=aarch64-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s 4 5define i32 @add_z_i8i32(i8 %v, i32 %lhs) minsize { 6; CHECK-LABEL: add_z_i8i32: 7; CHECK: // %bb.0: 8; CHECK-NEXT: add w0, w1, w0, uxtb 9; CHECK-NEXT: ret 10 %vz = zext i8 %v to i32 11 %r = add i32 %lhs, %vz 12 ret i32 %r 13} 14 15define i32 @add_z_shli8i32(i8 %v, i32 %lhs) minsize { 16; CHECK-LABEL: add_z_shli8i32: 17; CHECK: // %bb.0: 18; CHECK-NEXT: add w0, w1, w0, uxtb #3 19; CHECK-NEXT: ret 20 %vz = zext i8 %v to i32 21 %s = shl i32 %vz, 3 22 %r = add i32 %lhs, %s 23 ret i32 %r 24} 25 26define i64 @add_z_i8i64(i8 %v, i64 %lhs) minsize { 27; CHECK-LABEL: add_z_i8i64: 28; CHECK: // %bb.0: 29; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 30; CHECK-NEXT: add x0, x1, w0, uxtb 31; CHECK-NEXT: ret 32 %vz = zext i8 %v to i64 33 %r = add i64 %lhs, %vz 34 ret i64 %r 35} 36 37define i64 @add_z_shli8i64(i8 %v, i64 %lhs) minsize { 38; CHECK-LABEL: add_z_shli8i64: 39; CHECK: // %bb.0: 40; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 41; CHECK-NEXT: add x0, x1, w0, uxtb #3 42; CHECK-NEXT: ret 43 %vz = zext i8 %v to i64 44 %s = shl i64 %vz, 3 45 %r = add i64 %lhs, %s 46 ret i64 %r 47} 48 49define i32 @add_s_i8i32(i8 %v, i32 %lhs) minsize { 50; CHECK-LABEL: add_s_i8i32: 51; CHECK: // %bb.0: 52; CHECK-NEXT: add w0, w1, w0, sxtb 53; CHECK-NEXT: ret 54 %vz = sext i8 %v to i32 55 %r = add i32 %lhs, %vz 56 ret i32 %r 57} 58 59define i32 @add_s_shli8i32(i8 %v, i32 %lhs) minsize { 60; CHECK-LABEL: add_s_shli8i32: 61; CHECK: // %bb.0: 62; CHECK-NEXT: add w0, w1, w0, sxtb #3 63; CHECK-NEXT: ret 64 %vz = sext i8 %v to i32 65 %s = shl i32 %vz, 3 66 %r = add i32 %lhs, %s 67 ret i32 %r 68} 69 70define i64 @add_s_i8i64(i8 %v, i64 %lhs) minsize { 71; CHECK-LABEL: add_s_i8i64: 72; CHECK: // %bb.0: 73; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 74; CHECK-NEXT: add x0, x1, w0, sxtb 75; CHECK-NEXT: ret 76 %vz = sext i8 %v to i64 77 %r = add i64 %lhs, %vz 78 ret i64 %r 79} 80 81define i64 @add_s_shli8i64(i8 %v, i64 %lhs) minsize { 82; CHECK-LABEL: add_s_shli8i64: 83; CHECK: // %bb.0: 84; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 85; CHECK-NEXT: add x0, x1, w0, sxtb #3 86; CHECK-NEXT: ret 87 %vz = sext i8 %v to i64 88 %s = shl i64 %vz, 3 89 %r = add i64 %lhs, %s 90 ret i64 %r 91} 92 93define i32 @add_z_i16i32(i16 %v, i32 %lhs) minsize { 94; CHECK-LABEL: add_z_i16i32: 95; CHECK: // %bb.0: 96; CHECK-NEXT: add w0, w1, w0, uxth 97; CHECK-NEXT: ret 98 %vz = zext i16 %v to i32 99 %r = add i32 %lhs, %vz 100 ret i32 %r 101} 102 103define i32 @add_z_shli16i32(i16 %v, i32 %lhs) minsize { 104; CHECK-LABEL: add_z_shli16i32: 105; CHECK: // %bb.0: 106; CHECK-NEXT: add w0, w1, w0, uxth #3 107; CHECK-NEXT: ret 108 %vz = zext i16 %v to i32 109 %s = shl i32 %vz, 3 110 %r = add i32 %lhs, %s 111 ret i32 %r 112} 113 114define i64 @add_z_i16i64(i16 %v, i64 %lhs) minsize { 115; CHECK-LABEL: add_z_i16i64: 116; CHECK: // %bb.0: 117; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 118; CHECK-NEXT: add x0, x1, w0, uxth 119; CHECK-NEXT: ret 120 %vz = zext i16 %v to i64 121 %r = add i64 %lhs, %vz 122 ret i64 %r 123} 124 125define i64 @add_z_shli16i64(i16 %v, i64 %lhs) minsize { 126; CHECK-LABEL: add_z_shli16i64: 127; CHECK: // %bb.0: 128; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 129; CHECK-NEXT: add x0, x1, w0, uxth #3 130; CHECK-NEXT: ret 131 %vz = zext i16 %v to i64 132 %s = shl i64 %vz, 3 133 %r = add i64 %lhs, %s 134 ret i64 %r 135} 136 137define i64 @add_z_i32i64(i32 %v, i64 %lhs) minsize { 138; CHECK-LABEL: add_z_i32i64: 139; CHECK: // %bb.0: 140; CHECK-NEXT: add x0, x1, w0, uxtw 141; CHECK-NEXT: ret 142 %vz = zext i32 %v to i64 143 %r = add i64 %lhs, %vz 144 ret i64 %r 145} 146 147define i64 @add_z_shli32i64(i32 %v, i64 %lhs) minsize { 148; CHECK-LABEL: add_z_shli32i64: 149; CHECK: // %bb.0: 150; CHECK-NEXT: add x0, x1, w0, uxtw #3 151; CHECK-NEXT: ret 152 %vz = zext i32 %v to i64 153 %s = shl i64 %vz, 3 154 %r = add i64 %lhs, %s 155 ret i64 %r 156} 157 158define i32 @add_s_i16i32(i16 %v, i32 %lhs) minsize { 159; CHECK-LABEL: add_s_i16i32: 160; CHECK: // %bb.0: 161; CHECK-NEXT: add w0, w1, w0, sxth 162; CHECK-NEXT: ret 163 %vz = sext i16 %v to i32 164 %r = add i32 %lhs, %vz 165 ret i32 %r 166} 167 168define i32 @add_s_shli16i32(i16 %v, i32 %lhs) minsize { 169; CHECK-LABEL: add_s_shli16i32: 170; CHECK: // %bb.0: 171; CHECK-NEXT: add w0, w1, w0, sxth #3 172; CHECK-NEXT: ret 173 %vz = sext i16 %v to i32 174 %s = shl i32 %vz, 3 175 %r = add i32 %lhs, %s 176 ret i32 %r 177} 178 179define i64 @add_s_i16i64(i16 %v, i64 %lhs) minsize { 180; CHECK-LABEL: add_s_i16i64: 181; CHECK: // %bb.0: 182; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 183; CHECK-NEXT: add x0, x1, w0, sxth 184; CHECK-NEXT: ret 185 %vz = sext i16 %v to i64 186 %r = add i64 %lhs, %vz 187 ret i64 %r 188} 189 190define i64 @add_s_shli16i64(i16 %v, i64 %lhs) minsize { 191; CHECK-LABEL: add_s_shli16i64: 192; CHECK: // %bb.0: 193; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 194; CHECK-NEXT: add x0, x1, w0, sxth #3 195; CHECK-NEXT: ret 196 %vz = sext i16 %v to i64 197 %s = shl i64 %vz, 3 198 %r = add i64 %lhs, %s 199 ret i64 %r 200} 201 202define i64 @add_s_i32i64(i32 %v, i64 %lhs) minsize { 203; CHECK-LABEL: add_s_i32i64: 204; CHECK: // %bb.0: 205; CHECK-NEXT: add x0, x1, w0, sxtw 206; CHECK-NEXT: ret 207 %vz = sext i32 %v to i64 208 %r = add i64 %lhs, %vz 209 ret i64 %r 210} 211 212define i64 @add_s_shli32i64(i32 %v, i64 %lhs) minsize { 213; CHECK-LABEL: add_s_shli32i64: 214; CHECK: // %bb.0: 215; CHECK-NEXT: add x0, x1, w0, sxtw #3 216; CHECK-NEXT: ret 217 %vz = sext i32 %v to i64 218 %s = shl i64 %vz, 3 219 %r = add i64 %lhs, %s 220 ret i64 %r 221} 222 223define i32 @sub_z_i8i32(i8 %v, i32 %lhs) minsize { 224; CHECK-LABEL: sub_z_i8i32: 225; CHECK: // %bb.0: 226; CHECK-NEXT: sub w0, w1, w0, uxtb 227; CHECK-NEXT: ret 228 %vz = zext i8 %v to i32 229 %r = sub i32 %lhs, %vz 230 ret i32 %r 231} 232 233define i32 @sub_z_shli8i32(i8 %v, i32 %lhs) minsize { 234; CHECK-LABEL: sub_z_shli8i32: 235; CHECK: // %bb.0: 236; CHECK-NEXT: sub w0, w1, w0, uxtb #3 237; CHECK-NEXT: ret 238 %vz = zext i8 %v to i32 239 %s = shl i32 %vz, 3 240 %r = sub i32 %lhs, %s 241 ret i32 %r 242} 243 244define i64 @sub_z_i8i64(i8 %v, i64 %lhs) minsize { 245; CHECK-LABEL: sub_z_i8i64: 246; CHECK: // %bb.0: 247; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 248; CHECK-NEXT: sub x0, x1, w0, uxtb 249; CHECK-NEXT: ret 250 %vz = zext i8 %v to i64 251 %r = sub i64 %lhs, %vz 252 ret i64 %r 253} 254 255define i64 @sub_z_shli8i64(i8 %v, i64 %lhs) minsize { 256; CHECK-LABEL: sub_z_shli8i64: 257; CHECK: // %bb.0: 258; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 259; CHECK-NEXT: sub x0, x1, w0, uxtb #3 260; CHECK-NEXT: ret 261 %vz = zext i8 %v to i64 262 %s = shl i64 %vz, 3 263 %r = sub i64 %lhs, %s 264 ret i64 %r 265} 266 267define i32 @sub_s_i8i32(i8 %v, i32 %lhs) minsize { 268; CHECK-LABEL: sub_s_i8i32: 269; CHECK: // %bb.0: 270; CHECK-NEXT: sub w0, w1, w0, sxtb 271; CHECK-NEXT: ret 272 %vz = sext i8 %v to i32 273 %r = sub i32 %lhs, %vz 274 ret i32 %r 275} 276 277define i32 @sub_s_shli8i32(i8 %v, i32 %lhs) minsize { 278; CHECK-LABEL: sub_s_shli8i32: 279; CHECK: // %bb.0: 280; CHECK-NEXT: sub w0, w1, w0, sxtb #3 281; CHECK-NEXT: ret 282 %vz = sext i8 %v to i32 283 %s = shl i32 %vz, 3 284 %r = sub i32 %lhs, %s 285 ret i32 %r 286} 287 288define i64 @sub_s_i8i64(i8 %v, i64 %lhs) minsize { 289; CHECK-LABEL: sub_s_i8i64: 290; CHECK: // %bb.0: 291; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 292; CHECK-NEXT: sub x0, x1, w0, sxtb 293; CHECK-NEXT: ret 294 %vz = sext i8 %v to i64 295 %r = sub i64 %lhs, %vz 296 ret i64 %r 297} 298 299define i64 @sub_s_shli8i64(i8 %v, i64 %lhs) minsize { 300; CHECK-LABEL: sub_s_shli8i64: 301; CHECK: // %bb.0: 302; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 303; CHECK-NEXT: sub x0, x1, w0, sxtb #3 304; CHECK-NEXT: ret 305 %vz = sext i8 %v to i64 306 %s = shl i64 %vz, 3 307 %r = sub i64 %lhs, %s 308 ret i64 %r 309} 310 311define i32 @sub_z_i16i32(i16 %v, i32 %lhs) minsize { 312; CHECK-LABEL: sub_z_i16i32: 313; CHECK: // %bb.0: 314; CHECK-NEXT: sub w0, w1, w0, uxth 315; CHECK-NEXT: ret 316 %vz = zext i16 %v to i32 317 %r = sub i32 %lhs, %vz 318 ret i32 %r 319} 320 321define i32 @sub_z_shli16i32(i16 %v, i32 %lhs) minsize { 322; CHECK-LABEL: sub_z_shli16i32: 323; CHECK: // %bb.0: 324; CHECK-NEXT: sub w0, w1, w0, uxth #3 325; CHECK-NEXT: ret 326 %vz = zext i16 %v to i32 327 %s = shl i32 %vz, 3 328 %r = sub i32 %lhs, %s 329 ret i32 %r 330} 331 332define i64 @sub_z_i16i64(i16 %v, i64 %lhs) minsize { 333; CHECK-LABEL: sub_z_i16i64: 334; CHECK: // %bb.0: 335; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 336; CHECK-NEXT: sub x0, x1, w0, uxth 337; CHECK-NEXT: ret 338 %vz = zext i16 %v to i64 339 %r = sub i64 %lhs, %vz 340 ret i64 %r 341} 342 343define i64 @sub_z_shli16i64(i16 %v, i64 %lhs) minsize { 344; CHECK-LABEL: sub_z_shli16i64: 345; CHECK: // %bb.0: 346; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 347; CHECK-NEXT: sub x0, x1, w0, uxth #3 348; CHECK-NEXT: ret 349 %vz = zext i16 %v to i64 350 %s = shl i64 %vz, 3 351 %r = sub i64 %lhs, %s 352 ret i64 %r 353} 354 355define i64 @sub_z_i32i64(i32 %v, i64 %lhs) minsize { 356; CHECK-LABEL: sub_z_i32i64: 357; CHECK: // %bb.0: 358; CHECK-NEXT: sub x0, x1, w0, uxtw 359; CHECK-NEXT: ret 360 %vz = zext i32 %v to i64 361 %r = sub i64 %lhs, %vz 362 ret i64 %r 363} 364 365define i64 @sub_z_shli32i64(i32 %v, i64 %lhs) minsize { 366; CHECK-LABEL: sub_z_shli32i64: 367; CHECK: // %bb.0: 368; CHECK-NEXT: sub x0, x1, w0, uxtw #3 369; CHECK-NEXT: ret 370 %vz = zext i32 %v to i64 371 %s = shl i64 %vz, 3 372 %r = sub i64 %lhs, %s 373 ret i64 %r 374} 375 376define i32 @sub_s_i16i32(i16 %v, i32 %lhs) minsize { 377; CHECK-LABEL: sub_s_i16i32: 378; CHECK: // %bb.0: 379; CHECK-NEXT: sub w0, w1, w0, sxth 380; CHECK-NEXT: ret 381 %vz = sext i16 %v to i32 382 %r = sub i32 %lhs, %vz 383 ret i32 %r 384} 385 386define i32 @sub_s_shli16i32(i16 %v, i32 %lhs) minsize { 387; CHECK-LABEL: sub_s_shli16i32: 388; CHECK: // %bb.0: 389; CHECK-NEXT: sub w0, w1, w0, sxth #3 390; CHECK-NEXT: ret 391 %vz = sext i16 %v to i32 392 %s = shl i32 %vz, 3 393 %r = sub i32 %lhs, %s 394 ret i32 %r 395} 396 397define i64 @sub_s_i16i64(i16 %v, i64 %lhs) minsize { 398; CHECK-LABEL: sub_s_i16i64: 399; CHECK: // %bb.0: 400; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 401; CHECK-NEXT: sub x0, x1, w0, sxth 402; CHECK-NEXT: ret 403 %vz = sext i16 %v to i64 404 %r = sub i64 %lhs, %vz 405 ret i64 %r 406} 407 408define i64 @sub_s_shli16i64(i16 %v, i64 %lhs) minsize { 409; CHECK-LABEL: sub_s_shli16i64: 410; CHECK: // %bb.0: 411; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 412; CHECK-NEXT: sub x0, x1, w0, sxth #3 413; CHECK-NEXT: ret 414 %vz = sext i16 %v to i64 415 %s = shl i64 %vz, 3 416 %r = sub i64 %lhs, %s 417 ret i64 %r 418} 419 420define i64 @sub_s_i32i64(i32 %v, i64 %lhs) minsize { 421; CHECK-LABEL: sub_s_i32i64: 422; CHECK: // %bb.0: 423; CHECK-NEXT: sub x0, x1, w0, sxtw 424; CHECK-NEXT: ret 425 %vz = sext i32 %v to i64 426 %r = sub i64 %lhs, %vz 427 ret i64 %r 428} 429 430define i64 @sub_s_shli32i64(i32 %v, i64 %lhs) minsize { 431; CHECK-LABEL: sub_s_shli32i64: 432; CHECK: // %bb.0: 433; CHECK-NEXT: sub x0, x1, w0, sxtw #3 434; CHECK-NEXT: ret 435 %vz = sext i32 %v to i64 436 %s = shl i64 %vz, 3 437 %r = sub i64 %lhs, %s 438 ret i64 %r 439} 440 441define i32 @cmp_s_i8i32(i8 %v, i32 %lhs) minsize { 442; CHECK-LABEL: cmp_s_i8i32: 443; CHECK: // %bb.0: 444; CHECK-NEXT: cmp w1, w0, uxtb 445; CHECK-NEXT: b.ge .LBB40_2 446; CHECK-NEXT: // %bb.1: // %then 447; CHECK-NEXT: mov w0, #1 448; CHECK-NEXT: ret 449; CHECK-NEXT: .LBB40_2: // %end 450; CHECK-NEXT: mov w0, w1 451; CHECK-NEXT: ret 452 %vz = zext i8 %v to i32 453 %c = icmp slt i32 %lhs, %vz 454 br i1 %c, label %then, label %end 455then: 456 ret i32 1 457end: 458 ret i32 %lhs 459} 460 461define i64 @cmp_s_i8i64(i8 %v, i64 %lhs) minsize { 462; CHECK-LABEL: cmp_s_i8i64: 463; CHECK: // %bb.0: 464; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 465; CHECK-NEXT: cmp x1, w0, sxtb 466; CHECK-NEXT: b.ge .LBB41_2 467; CHECK-NEXT: // %bb.1: // %then 468; CHECK-NEXT: mov w0, #1 469; CHECK-NEXT: ret 470; CHECK-NEXT: .LBB41_2: // %end 471; CHECK-NEXT: mov x0, x1 472; CHECK-NEXT: ret 473 %vz = sext i8 %v to i64 474 %c = icmp slt i64 %lhs, %vz 475 br i1 %c, label %then, label %end 476then: 477 ret i64 1 478end: 479 ret i64 %lhs 480} 481 482define i32 @cmp_s_i16i32(i16 %v, i32 %lhs) minsize { 483; CHECK-LABEL: cmp_s_i16i32: 484; CHECK: // %bb.0: 485; CHECK-NEXT: cmp w1, w0, uxth 486; CHECK-NEXT: b.ge .LBB42_2 487; CHECK-NEXT: // %bb.1: // %then 488; CHECK-NEXT: mov w0, #1 489; CHECK-NEXT: ret 490; CHECK-NEXT: .LBB42_2: // %end 491; CHECK-NEXT: mov w0, w1 492; CHECK-NEXT: ret 493 %vz = zext i16 %v to i32 494 %c = icmp slt i32 %lhs, %vz 495 br i1 %c, label %then, label %end 496then: 497 ret i32 1 498end: 499 ret i32 %lhs 500} 501 502define i64 @cmp_s_i16i64(i16 %v, i64 %lhs) minsize { 503; CHECK-LABEL: cmp_s_i16i64: 504; CHECK: // %bb.0: 505; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 506; CHECK-NEXT: cmp x1, w0, sxth 507; CHECK-NEXT: b.ge .LBB43_2 508; CHECK-NEXT: // %bb.1: // %then 509; CHECK-NEXT: mov w0, #1 510; CHECK-NEXT: ret 511; CHECK-NEXT: .LBB43_2: // %end 512; CHECK-NEXT: mov x0, x1 513; CHECK-NEXT: ret 514 %vz = sext i16 %v to i64 515 %c = icmp slt i64 %lhs, %vz 516 br i1 %c, label %then, label %end 517then: 518 ret i64 1 519end: 520 ret i64 %lhs 521} 522 523 524; Check that implicit zext from w reg write is used instead of uxtw form of add. 525define dso_local i64 @add_fold_uxtw(i32 %x, i64 %y) { 526; CHECK-LABEL: add_fold_uxtw: 527; CHECK: // %bb.0: // %entry 528; CHECK-NEXT: and w8, w0, #0x3 529; CHECK-NEXT: add x0, x1, x8 530; CHECK-NEXT: ret 531entry: 532 %m = and i32 %x, 3 533 %ext = zext i32 %m to i64 534 %ret = add i64 %y, %ext 535 ret i64 %ret 536} 537 538; Check that implicit zext from w reg write is used instead of uxtw 539; form of sub and that mov WZR is folded to form a neg instruction. 540define dso_local i64 @sub_fold_uxtw_xzr(i32 %x) { 541; CHECK-LABEL: sub_fold_uxtw_xzr: 542; CHECK: // %bb.0: // %entry 543; CHECK-NEXT: and w8, w0, #0x3 544; CHECK-NEXT: neg x0, x8 545; CHECK-NEXT: ret 546entry: 547 %m = and i32 %x, 3 548 %ext = zext i32 %m to i64 549 %ret = sub i64 0, %ext 550 ret i64 %ret 551} 552 553; Check that implicit zext from w reg write is used instead of uxtw form of subs/cmp. 554define dso_local i1 @cmp_fold_uxtw(i32 %x, i64 %y) { 555; CHECK-LABEL: cmp_fold_uxtw: 556; CHECK: // %bb.0: // %entry 557; CHECK-NEXT: and w8, w0, #0x3 558; CHECK-NEXT: cmp x1, x8 559; CHECK-NEXT: cset w0, eq 560; CHECK-NEXT: ret 561entry: 562 %m = and i32 %x, 3 563 %ext = zext i32 %m to i64 564 %ret = icmp eq i64 %y, %ext 565 ret i1 %ret 566} 567 568; Check that implicit zext from w reg write is used instead of uxtw 569; form of add, leading to madd selection. 570define dso_local i64 @madd_fold_uxtw(i32 %x, i64 %y) { 571; CHECK-LABEL: madd_fold_uxtw: 572; CHECK: // %bb.0: // %entry 573; CHECK-NEXT: and w8, w0, #0x3 574; CHECK-NEXT: madd x0, x1, x1, x8 575; CHECK-NEXT: ret 576entry: 577 %m = and i32 %x, 3 578 %ext = zext i32 %m to i64 579 %mul = mul i64 %y, %y 580 %ret = add i64 %mul, %ext 581 ret i64 %ret 582} 583 584; Check that implicit zext from w reg write is used instead of uxtw 585; form of sub, leading to sub/cmp folding. 586; Check that implicit zext from w reg write is used instead of uxtw form of subs/cmp. 587define dso_local i1 @cmp_sub_fold_uxtw(i32 %x, i64 %y, i64 %z) { 588; CHECK-LABEL: cmp_sub_fold_uxtw: 589; CHECK: // %bb.0: // %entry 590; CHECK-NEXT: and w8, w0, #0x3 591; CHECK-NEXT: cmp x2, x8 592; CHECK-NEXT: cset w0, eq 593; CHECK-NEXT: ret 594entry: 595 %m = and i32 %x, 3 596 %ext = zext i32 %m to i64 597 %sub = sub i64 %z, %ext 598 %ret = icmp eq i64 %sub, 0 599 ret i1 %ret 600} 601 602; Check that implicit zext from w reg write is used instead of uxtw 603; form of add and add of -1 gets selected as sub. 604define dso_local i64 @add_imm_fold_uxtw(i32 %x) { 605; CHECK-LABEL: add_imm_fold_uxtw: 606; CHECK: // %bb.0: // %entry 607; CHECK-NEXT: and w8, w0, #0x3 608; CHECK-NEXT: sub x0, x8, #1 609; CHECK-NEXT: ret 610entry: 611 %m = and i32 %x, 3 612 %ext = zext i32 %m to i64 613 %ret = add i64 %ext, -1 614 ret i64 %ret 615} 616 617; Check that implicit zext from w reg write is used instead of uxtw 618; form of add and add lsl form gets selected. 619define dso_local i64 @add_lsl_fold_uxtw(i32 %x, i64 %y) { 620; CHECK-LABEL: add_lsl_fold_uxtw: 621; CHECK: // %bb.0: // %entry 622; CHECK-NEXT: orr w8, w0, #0x3 623; CHECK-NEXT: add x0, x8, x1, lsl #3 624; CHECK-NEXT: ret 625entry: 626 %m = or i32 %x, 3 627 %ext = zext i32 %m to i64 628 %shift = shl i64 %y, 3 629 %ret = add i64 %ext, %shift 630 ret i64 %ret 631} 632