1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc --verify-machineinstrs -mtriple=thumbv8.1m.main-none-eabi -mattr=+mve %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-MVE 3; RUN: llc --verify-machineinstrs -mtriple=thumbv8.1m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-NON-MVE 4 5define i64 @shift_left_reg(i64 %x, i64 %y) { 6; CHECK-MVE-LABEL: shift_left_reg: 7; CHECK-MVE: @ %bb.0: @ %entry 8; CHECK-MVE-NEXT: lsll r0, r1, r2 9; CHECK-MVE-NEXT: bx lr 10; 11; CHECK-NON-MVE-LABEL: shift_left_reg: 12; CHECK-NON-MVE: @ %bb.0: @ %entry 13; CHECK-NON-MVE-NEXT: rsb.w r3, r2, #32 14; CHECK-NON-MVE-NEXT: lsls r1, r2 15; CHECK-NON-MVE-NEXT: lsr.w r3, r0, r3 16; CHECK-NON-MVE-NEXT: orrs r1, r3 17; CHECK-NON-MVE-NEXT: subs.w r3, r2, #32 18; CHECK-NON-MVE-NEXT: it pl 19; CHECK-NON-MVE-NEXT: lslpl.w r1, r0, r3 20; CHECK-NON-MVE-NEXT: lsl.w r0, r0, r2 21; CHECK-NON-MVE-NEXT: it pl 22; CHECK-NON-MVE-NEXT: movpl r0, #0 23; CHECK-NON-MVE-NEXT: bx lr 24entry: 25 %shl = shl i64 %x, %y 26 ret i64 %shl 27} 28 29define i64 @shift_left_imm(i64 %x) { 30; CHECK-MVE-LABEL: shift_left_imm: 31; CHECK-MVE: @ %bb.0: @ %entry 32; CHECK-MVE-NEXT: lsll r0, r1, #3 33; CHECK-MVE-NEXT: bx lr 34; 35; CHECK-NON-MVE-LABEL: shift_left_imm: 36; CHECK-NON-MVE: @ %bb.0: @ %entry 37; CHECK-NON-MVE-NEXT: lsls r1, r1, #3 38; CHECK-NON-MVE-NEXT: orr.w r1, r1, r0, lsr #29 39; CHECK-NON-MVE-NEXT: lsls r0, r0, #3 40; CHECK-NON-MVE-NEXT: bx lr 41entry: 42 %shl = shl i64 %x, 3 43 ret i64 %shl 44} 45 46define i64 @shift_left_imm_big(i64 %x) { 47; CHECK-LABEL: shift_left_imm_big: 48; CHECK: @ %bb.0: @ %entry 49; CHECK-NEXT: lsls r1, r0, #16 50; CHECK-NEXT: movs r0, #0 51; CHECK-NEXT: bx lr 52entry: 53 %shl = shl i64 %x, 48 54 ret i64 %shl 55} 56 57define i64 @shift_left_imm_big2(i64 %x) { 58; CHECK-LABEL: shift_left_imm_big2: 59; CHECK: @ %bb.0: @ %entry 60; CHECK-NEXT: mov r1, r0 61; CHECK-NEXT: movs r0, #0 62; CHECK-NEXT: bx lr 63entry: 64 %shl = shl i64 %x, 32 65 ret i64 %shl 66} 67 68define i64 @shift_left_imm_big3(i64 %x) { 69; CHECK-LABEL: shift_left_imm_big3: 70; CHECK: @ %bb.0: @ %entry 71; CHECK-NEXT: lsls r1, r0, #1 72; CHECK-NEXT: movs r0, #0 73; CHECK-NEXT: bx lr 74entry: 75 %shl = shl i64 %x, 33 76 ret i64 %shl 77} 78 79define i64 @shift_right_reg(i64 %x, i64 %y) { 80; CHECK-MVE-LABEL: shift_right_reg: 81; CHECK-MVE: @ %bb.0: @ %entry 82; CHECK-MVE-NEXT: rsbs r2, r2, #0 83; CHECK-MVE-NEXT: lsll r0, r1, r2 84; CHECK-MVE-NEXT: bx lr 85; 86; CHECK-NON-MVE-LABEL: shift_right_reg: 87; CHECK-NON-MVE: @ %bb.0: @ %entry 88; CHECK-NON-MVE-NEXT: rsb.w r3, r2, #32 89; CHECK-NON-MVE-NEXT: lsrs r0, r2 90; CHECK-NON-MVE-NEXT: lsl.w r3, r1, r3 91; CHECK-NON-MVE-NEXT: orrs r0, r3 92; CHECK-NON-MVE-NEXT: subs.w r3, r2, #32 93; CHECK-NON-MVE-NEXT: it pl 94; CHECK-NON-MVE-NEXT: lsrpl.w r0, r1, r3 95; CHECK-NON-MVE-NEXT: lsr.w r1, r1, r2 96; CHECK-NON-MVE-NEXT: it pl 97; CHECK-NON-MVE-NEXT: movpl r1, #0 98; CHECK-NON-MVE-NEXT: bx lr 99entry: 100 %shr = lshr i64 %x, %y 101 ret i64 %shr 102} 103 104define i64 @shift_right_imm(i64 %x) { 105; CHECK-MVE-LABEL: shift_right_imm: 106; CHECK-MVE: @ %bb.0: @ %entry 107; CHECK-MVE-NEXT: lsrl r0, r1, #3 108; CHECK-MVE-NEXT: bx lr 109; 110; CHECK-NON-MVE-LABEL: shift_right_imm: 111; CHECK-NON-MVE: @ %bb.0: @ %entry 112; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3 113; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29 114; CHECK-NON-MVE-NEXT: lsrs r1, r1, #3 115; CHECK-NON-MVE-NEXT: bx lr 116entry: 117 %shr = lshr i64 %x, 3 118 ret i64 %shr 119} 120 121define i64 @shift_right_imm_big(i64 %x) { 122; CHECK-LABEL: shift_right_imm_big: 123; CHECK: @ %bb.0: @ %entry 124; CHECK-NEXT: lsrs r0, r1, #16 125; CHECK-NEXT: movs r1, #0 126; CHECK-NEXT: bx lr 127entry: 128 %shr = lshr i64 %x, 48 129 ret i64 %shr 130} 131 132define i64 @shift_right_imm_big2(i64 %x) { 133; CHECK-LABEL: shift_right_imm_big2: 134; CHECK: @ %bb.0: @ %entry 135; CHECK-NEXT: mov r0, r1 136; CHECK-NEXT: movs r1, #0 137; CHECK-NEXT: bx lr 138entry: 139 %shr = lshr i64 %x, 32 140 ret i64 %shr 141} 142 143define i64 @shift_right_imm_big3(i64 %x) { 144; CHECK-LABEL: shift_right_imm_big3: 145; CHECK: @ %bb.0: @ %entry 146; CHECK-NEXT: lsrs r0, r1, #1 147; CHECK-NEXT: movs r1, #0 148; CHECK-NEXT: bx lr 149entry: 150 %shr = lshr i64 %x, 33 151 ret i64 %shr 152} 153 154define i64 @shift_arithmetic_right_reg(i64 %x, i64 %y) { 155; CHECK-MVE-LABEL: shift_arithmetic_right_reg: 156; CHECK-MVE: @ %bb.0: @ %entry 157; CHECK-MVE-NEXT: asrl r0, r1, r2 158; CHECK-MVE-NEXT: bx lr 159; 160; CHECK-NON-MVE-LABEL: shift_arithmetic_right_reg: 161; CHECK-NON-MVE: @ %bb.0: @ %entry 162; CHECK-NON-MVE-NEXT: rsb.w r3, r2, #32 163; CHECK-NON-MVE-NEXT: lsrs r0, r2 164; CHECK-NON-MVE-NEXT: lsl.w r3, r1, r3 165; CHECK-NON-MVE-NEXT: orrs r0, r3 166; CHECK-NON-MVE-NEXT: subs.w r3, r2, #32 167; CHECK-NON-MVE-NEXT: asr.w r2, r1, r2 168; CHECK-NON-MVE-NEXT: it pl 169; CHECK-NON-MVE-NEXT: asrpl.w r0, r1, r3 170; CHECK-NON-MVE-NEXT: it pl 171; CHECK-NON-MVE-NEXT: asrpl r2, r1, #31 172; CHECK-NON-MVE-NEXT: mov r1, r2 173; CHECK-NON-MVE-NEXT: bx lr 174entry: 175 %shr = ashr i64 %x, %y 176 ret i64 %shr 177} 178 179define i64 @shift_arithmetic_right_imm(i64 %x) { 180; CHECK-MVE-LABEL: shift_arithmetic_right_imm: 181; CHECK-MVE: @ %bb.0: @ %entry 182; CHECK-MVE-NEXT: asrl r0, r1, #3 183; CHECK-MVE-NEXT: bx lr 184; 185; CHECK-NON-MVE-LABEL: shift_arithmetic_right_imm: 186; CHECK-NON-MVE: @ %bb.0: @ %entry 187; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3 188; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29 189; CHECK-NON-MVE-NEXT: asrs r1, r1, #3 190; CHECK-NON-MVE-NEXT: bx lr 191entry: 192 %shr = ashr i64 %x, 3 193 ret i64 %shr 194} 195 196%struct.bar = type { i16, i8, [5 x i8] } 197 198define arm_aapcs_vfpcc void @fn1(ptr nocapture %a) { 199; CHECK-MVE-LABEL: fn1: 200; CHECK-MVE: @ %bb.0: @ %entry 201; CHECK-MVE-NEXT: ldr r2, [r0, #4] 202; CHECK-MVE-NEXT: movs r1, #0 203; CHECK-MVE-NEXT: lsll r2, r1, #8 204; CHECK-MVE-NEXT: strb r1, [r0, #7] 205; CHECK-MVE-NEXT: str.w r2, [r0, #3] 206; CHECK-MVE-NEXT: bx lr 207; 208; CHECK-NON-MVE-LABEL: fn1: 209; CHECK-NON-MVE: @ %bb.0: @ %entry 210; CHECK-NON-MVE-NEXT: ldr r1, [r0, #4] 211; CHECK-NON-MVE-NEXT: lsrs r2, r1, #24 212; CHECK-NON-MVE-NEXT: lsls r1, r1, #8 213; CHECK-NON-MVE-NEXT: strb r2, [r0, #7] 214; CHECK-NON-MVE-NEXT: str.w r1, [r0, #3] 215; CHECK-NON-MVE-NEXT: bx lr 216entry: 217 %carey = getelementptr inbounds %struct.bar, ptr %a, i32 0, i32 2 218 %bf.load = load i40, ptr %carey, align 1 219 %bf.clear = and i40 %bf.load, -256 220 store i40 %bf.clear, ptr %carey, align 1 221 ret void 222} 223 224%struct.a = type { i96 } 225 226define void @lsll_128bit_shift(ptr nocapture %x) local_unnamed_addr #0 { 227; CHECK-LABEL: lsll_128bit_shift: 228; CHECK: @ %bb.0: @ %entry 229; CHECK-NEXT: movs r1, #0 230; CHECK-NEXT: strd r1, r1, [r0] 231; CHECK-NEXT: str r1, [r0, #8] 232; CHECK-NEXT: bx lr 233entry: 234 %bf.load = load i128, ptr %x, align 8 235 %bf.clear4 = and i128 %bf.load, -79228162514264337593543950336 236 store i128 %bf.clear4, ptr %x, align 8 237 ret void 238} 239 240%struct.b = type { i184 } 241 242define void @lsll_256bit_shift(ptr nocapture %x) local_unnamed_addr #0 { 243; CHECK-LABEL: lsll_256bit_shift: 244; CHECK: @ %bb.0: @ %entry 245; CHECK-NEXT: movs r1, #0 246; CHECK-NEXT: str r1, [r0, #16] 247; CHECK-NEXT: strd r1, r1, [r0, #8] 248; CHECK-NEXT: strd r1, r1, [r0] 249; CHECK-NEXT: ldrb r1, [r0, #23] 250; CHECK-NEXT: lsls r1, r1, #24 251; CHECK-NEXT: str r1, [r0, #20] 252; CHECK-NEXT: bx lr 253entry: 254 %bf.load = load i192, ptr %x, align 8 255 %bf.clear4 = and i192 %bf.load, -24519928653854221733733552434404946937899825954937634816 256 store i192 %bf.clear4, ptr %x, align 8 257 ret void 258} 259 260 261define i32 @ashr_demand_bottom3(i64 %x) { 262; CHECK-MVE-LABEL: ashr_demand_bottom3: 263; CHECK-MVE: @ %bb.0: @ %entry 264; CHECK-MVE-NEXT: lsrl r0, r1, #3 265; CHECK-MVE-NEXT: bx lr 266; 267; CHECK-NON-MVE-LABEL: ashr_demand_bottom3: 268; CHECK-NON-MVE: @ %bb.0: @ %entry 269; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3 270; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29 271; CHECK-NON-MVE-NEXT: bx lr 272entry: 273 %shr = ashr i64 %x, 3 274 %t = trunc i64 %shr to i32 275 ret i32 %t 276} 277 278define i32 @lshr_demand_bottom3(i64 %x) { 279; CHECK-MVE-LABEL: lshr_demand_bottom3: 280; CHECK-MVE: @ %bb.0: @ %entry 281; CHECK-MVE-NEXT: lsrl r0, r1, #3 282; CHECK-MVE-NEXT: bx lr 283; 284; CHECK-NON-MVE-LABEL: lshr_demand_bottom3: 285; CHECK-NON-MVE: @ %bb.0: @ %entry 286; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3 287; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29 288; CHECK-NON-MVE-NEXT: bx lr 289entry: 290 %shr = lshr i64 %x, 3 291 %t = trunc i64 %shr to i32 292 ret i32 %t 293} 294 295define i32 @lsl_demand_bottom3(i64 %x) { 296; CHECK-LABEL: lsl_demand_bottom3: 297; CHECK: @ %bb.0: @ %entry 298; CHECK-NEXT: lsls r0, r0, #3 299; CHECK-NEXT: bx lr 300entry: 301 %shr = shl i64 %x, 3 302 %t = trunc i64 %shr to i32 303 ret i32 %t 304} 305 306 307define i32 @ashr_demand_bottom31(i64 %x) { 308; CHECK-MVE-LABEL: ashr_demand_bottom31: 309; CHECK-MVE: @ %bb.0: @ %entry 310; CHECK-MVE-NEXT: lsrl r0, r1, #31 311; CHECK-MVE-NEXT: bx lr 312; 313; CHECK-NON-MVE-LABEL: ashr_demand_bottom31: 314; CHECK-NON-MVE: @ %bb.0: @ %entry 315; CHECK-NON-MVE-NEXT: lsrs r0, r0, #31 316; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #1 317; CHECK-NON-MVE-NEXT: bx lr 318entry: 319 %shr = ashr i64 %x, 31 320 %t = trunc i64 %shr to i32 321 ret i32 %t 322} 323 324define i32 @lshr_demand_bottom31(i64 %x) { 325; CHECK-MVE-LABEL: lshr_demand_bottom31: 326; CHECK-MVE: @ %bb.0: @ %entry 327; CHECK-MVE-NEXT: lsrl r0, r1, #31 328; CHECK-MVE-NEXT: bx lr 329; 330; CHECK-NON-MVE-LABEL: lshr_demand_bottom31: 331; CHECK-NON-MVE: @ %bb.0: @ %entry 332; CHECK-NON-MVE-NEXT: lsrs r0, r0, #31 333; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #1 334; CHECK-NON-MVE-NEXT: bx lr 335entry: 336 %shr = lshr i64 %x, 31 337 %t = trunc i64 %shr to i32 338 ret i32 %t 339} 340 341define i32 @lsl_demand_bottom31(i64 %x) { 342; CHECK-LABEL: lsl_demand_bottom31: 343; CHECK: @ %bb.0: @ %entry 344; CHECK-NEXT: lsls r0, r0, #31 345; CHECK-NEXT: bx lr 346entry: 347 %shr = shl i64 %x, 31 348 %t = trunc i64 %shr to i32 349 ret i32 %t 350} 351 352 353define i32 @ashr_demand_bottom32(i64 %x) { 354; CHECK-LABEL: ashr_demand_bottom32: 355; CHECK: @ %bb.0: @ %entry 356; CHECK-NEXT: mov r0, r1 357; CHECK-NEXT: bx lr 358entry: 359 %shr = ashr i64 %x, 32 360 %t = trunc i64 %shr to i32 361 ret i32 %t 362} 363 364define i32 @lshr_demand_bottom32(i64 %x) { 365; CHECK-LABEL: lshr_demand_bottom32: 366; CHECK: @ %bb.0: @ %entry 367; CHECK-NEXT: mov r0, r1 368; CHECK-NEXT: bx lr 369entry: 370 %shr = lshr i64 %x, 32 371 %t = trunc i64 %shr to i32 372 ret i32 %t 373} 374 375define i32 @lsl_demand_bottom32(i64 %x) { 376; CHECK-LABEL: lsl_demand_bottom32: 377; CHECK: @ %bb.0: @ %entry 378; CHECK-NEXT: movs r0, #0 379; CHECK-NEXT: bx lr 380entry: 381 %shr = shl i64 %x, 32 382 %t = trunc i64 %shr to i32 383 ret i32 %t 384} 385 386 387define i32 @ashr_demand_bottom44(i64 %x) { 388; CHECK-LABEL: ashr_demand_bottom44: 389; CHECK: @ %bb.0: @ %entry 390; CHECK-NEXT: asrs r0, r1, #12 391; CHECK-NEXT: bx lr 392entry: 393 %shr = ashr i64 %x, 44 394 %t = trunc i64 %shr to i32 395 ret i32 %t 396} 397 398define i32 @lshr_demand_bottom44(i64 %x) { 399; CHECK-LABEL: lshr_demand_bottom44: 400; CHECK: @ %bb.0: @ %entry 401; CHECK-NEXT: lsrs r0, r1, #12 402; CHECK-NEXT: bx lr 403entry: 404 %shr = lshr i64 %x, 44 405 %t = trunc i64 %shr to i32 406 ret i32 %t 407} 408 409define i32 @lsl_demand_bottom44(i64 %x) { 410; CHECK-LABEL: lsl_demand_bottom44: 411; CHECK: @ %bb.0: @ %entry 412; CHECK-NEXT: movs r0, #0 413; CHECK-NEXT: bx lr 414entry: 415 %shr = shl i64 %x, 44 416 %t = trunc i64 %shr to i32 417 ret i32 %t 418} 419 420 421define i32 @ashr_demand_bottommask(i64 %x) { 422; CHECK-LABEL: ashr_demand_bottommask: 423; CHECK: @ %bb.0: @ %entry 424; CHECK-NEXT: lsls r0, r1, #1 425; CHECK-NEXT: bx lr 426entry: 427 %shr = ashr i64 %x, 31 428 %t = trunc i64 %shr to i32 429 %a = and i32 %t, -2 430 ret i32 %a 431} 432 433define i32 @lshr_demand_bottommask(i64 %x) { 434; CHECK-LABEL: lshr_demand_bottommask: 435; CHECK: @ %bb.0: @ %entry 436; CHECK-NEXT: lsls r0, r1, #1 437; CHECK-NEXT: bx lr 438entry: 439 %shr = lshr i64 %x, 31 440 %t = trunc i64 %shr to i32 441 %a = and i32 %t, -2 442 ret i32 %a 443} 444 445define i32 @lsl_demand_bottommask(i64 %x) { 446; CHECK-LABEL: lsl_demand_bottommask: 447; CHECK: @ %bb.0: @ %entry 448; CHECK-NEXT: lsls r0, r0, #31 449; CHECK-NEXT: bx lr 450entry: 451 %shr = shl i64 %x, 31 452 %t = trunc i64 %shr to i32 453 %a = and i32 %t, -2 454 ret i32 %a 455} 456 457define i32 @ashr_demand_bottommask2(i64 %x) { 458; CHECK-LABEL: ashr_demand_bottommask2: 459; CHECK: @ %bb.0: @ %entry 460; CHECK-NEXT: mvn r0, #2 461; CHECK-NEXT: and.w r0, r0, r1, lsl #1 462; CHECK-NEXT: bx lr 463entry: 464 %shr = ashr i64 %x, 31 465 %t = trunc i64 %shr to i32 466 %a = and i32 %t, -4 467 ret i32 %a 468} 469 470define i32 @lshr_demand_bottommask2(i64 %x) { 471; CHECK-LABEL: lshr_demand_bottommask2: 472; CHECK: @ %bb.0: @ %entry 473; CHECK-NEXT: mvn r0, #2 474; CHECK-NEXT: and.w r0, r0, r1, lsl #1 475; CHECK-NEXT: bx lr 476entry: 477 %shr = lshr i64 %x, 31 478 %t = trunc i64 %shr to i32 479 %a = and i32 %t, -4 480 ret i32 %a 481} 482 483define i32 @lsl_demand_bottommask2(i64 %x) { 484; CHECK-LABEL: lsl_demand_bottommask2: 485; CHECK: @ %bb.0: @ %entry 486; CHECK-NEXT: lsls r0, r0, #31 487; CHECK-NEXT: bx lr 488entry: 489 %shr = shl i64 %x, 31 490 %t = trunc i64 %shr to i32 491 %a = and i32 %t, -4 492 ret i32 %a 493} 494 495define i32 @lsl_demand_topmask(i64 %x) { 496; CHECK-LABEL: lsl_demand_topmask: 497; CHECK: @ %bb.0: @ %entry 498; CHECK-NEXT: ubfx r0, r0, #1, #28 499; CHECK-NEXT: bx lr 500entry: 501 %sh = shl i64 %x, 31 502 %a = and i64 %sh, 1152921500311879680 ;0x0fffffff00000000 503 %l = ashr i64 %a, 32 504 %t = trunc i64 %l to i32 505 ret i32 %t 506} 507