1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv64 -global-isel -mattr=+m -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefixes=CHECK,RV64I 4; RUN: llc -mtriple=riscv64 -global-isel -mattr=+m,+zba -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBANOZBB 6; RUN: llc -mtriple=riscv64 -global-isel -mattr=+m,+zba,+zbb -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB 8 9define i64 @slliuw(i64 %a) nounwind { 10; RV64I-LABEL: slliuw: 11; RV64I: # %bb.0: 12; RV64I-NEXT: li a1, 1 13; RV64I-NEXT: slli a1, a1, 33 14; RV64I-NEXT: addi a1, a1, -2 15; RV64I-NEXT: slli a0, a0, 1 16; RV64I-NEXT: and a0, a0, a1 17; RV64I-NEXT: ret 18; 19; RV64ZBA-LABEL: slliuw: 20; RV64ZBA: # %bb.0: 21; RV64ZBA-NEXT: slli a0, a0, 1 22; RV64ZBA-NEXT: srli a0, a0, 1 23; RV64ZBA-NEXT: slli.uw a0, a0, 1 24; RV64ZBA-NEXT: ret 25 %conv1 = shl i64 %a, 1 26 %shl = and i64 %conv1, 8589934590 27 ret i64 %shl 28} 29 30define i128 @slliuw_2(i32 signext %0, ptr %1) { 31; RV64I-LABEL: slliuw_2: 32; RV64I: # %bb.0: 33; RV64I-NEXT: slli a0, a0, 32 34; RV64I-NEXT: srli a0, a0, 28 35; RV64I-NEXT: add a1, a1, a0 36; RV64I-NEXT: ld a0, 0(a1) 37; RV64I-NEXT: ld a1, 8(a1) 38; RV64I-NEXT: ret 39; 40; RV64ZBA-LABEL: slliuw_2: 41; RV64ZBA: # %bb.0: 42; RV64ZBA-NEXT: slli.uw a0, a0, 4 43; RV64ZBA-NEXT: add a1, a1, a0 44; RV64ZBA-NEXT: ld a0, 0(a1) 45; RV64ZBA-NEXT: ld a1, 8(a1) 46; RV64ZBA-NEXT: ret 47 %3 = zext i32 %0 to i64 48 %4 = getelementptr inbounds i128, ptr %1, i64 %3 49 %5 = load i128, ptr %4 50 ret i128 %5 51} 52 53define i64 @adduw(i64 %a, i64 %b) nounwind { 54; RV64I-LABEL: adduw: 55; RV64I: # %bb.0: 56; RV64I-NEXT: slli a1, a1, 32 57; RV64I-NEXT: srli a1, a1, 32 58; RV64I-NEXT: add a0, a1, a0 59; RV64I-NEXT: ret 60; 61; RV64ZBA-LABEL: adduw: 62; RV64ZBA: # %bb.0: 63; RV64ZBA-NEXT: add.uw a0, a1, a0 64; RV64ZBA-NEXT: ret 65 %and = and i64 %b, 4294967295 66 %add = add i64 %and, %a 67 ret i64 %add 68} 69 70define signext i8 @adduw_2(i32 signext %0, ptr %1) { 71; RV64I-LABEL: adduw_2: 72; RV64I: # %bb.0: 73; RV64I-NEXT: slli a0, a0, 32 74; RV64I-NEXT: srli a0, a0, 32 75; RV64I-NEXT: add a0, a1, a0 76; RV64I-NEXT: lb a0, 0(a0) 77; RV64I-NEXT: ret 78; 79; RV64ZBA-LABEL: adduw_2: 80; RV64ZBA: # %bb.0: 81; RV64ZBA-NEXT: add.uw a0, a0, a1 82; RV64ZBA-NEXT: lb a0, 0(a0) 83; RV64ZBA-NEXT: ret 84 %3 = zext i32 %0 to i64 85 %4 = getelementptr inbounds i8, ptr %1, i64 %3 86 %5 = load i8, ptr %4 87 ret i8 %5 88} 89 90define i64 @zextw_i64(i64 %a) nounwind { 91; RV64I-LABEL: zextw_i64: 92; RV64I: # %bb.0: 93; RV64I-NEXT: slli a0, a0, 32 94; RV64I-NEXT: srli a0, a0, 32 95; RV64I-NEXT: ret 96; 97; RV64ZBA-LABEL: zextw_i64: 98; RV64ZBA: # %bb.0: 99; RV64ZBA-NEXT: zext.w a0, a0 100; RV64ZBA-NEXT: ret 101 %and = and i64 %a, 4294967295 102 ret i64 %and 103} 104 105; This makes sure targetShrinkDemandedConstant changes the and immmediate to 106; allow zext.w or slli+srli. 107define i64 @zextw_demandedbits_i64(i64 %0) { 108; CHECK-LABEL: zextw_demandedbits_i64: 109; CHECK: # %bb.0: 110; CHECK-NEXT: srliw a0, a0, 1 111; CHECK-NEXT: slli a0, a0, 1 112; CHECK-NEXT: ori a0, a0, 1 113; CHECK-NEXT: ret 114 %2 = and i64 %0, 4294967294 115 %3 = or i64 %2, 1 116 ret i64 %3 117} 118 119define signext i16 @sh1add(i64 %0, ptr %1) { 120; RV64I-LABEL: sh1add: 121; RV64I: # %bb.0: 122; RV64I-NEXT: slli a0, a0, 1 123; RV64I-NEXT: add a0, a1, a0 124; RV64I-NEXT: lh a0, 0(a0) 125; RV64I-NEXT: ret 126; 127; RV64ZBA-LABEL: sh1add: 128; RV64ZBA: # %bb.0: 129; RV64ZBA-NEXT: sh1add a0, a0, a1 130; RV64ZBA-NEXT: lh a0, 0(a0) 131; RV64ZBA-NEXT: ret 132 %3 = getelementptr inbounds i16, ptr %1, i64 %0 133 %4 = load i16, ptr %3 134 ret i16 %4 135} 136 137define signext i32 @sh2add(i64 %0, ptr %1) { 138; RV64I-LABEL: sh2add: 139; RV64I: # %bb.0: 140; RV64I-NEXT: slli a0, a0, 2 141; RV64I-NEXT: add a0, a1, a0 142; RV64I-NEXT: lw a0, 0(a0) 143; RV64I-NEXT: ret 144; 145; RV64ZBA-LABEL: sh2add: 146; RV64ZBA: # %bb.0: 147; RV64ZBA-NEXT: sh2add a0, a0, a1 148; RV64ZBA-NEXT: lw a0, 0(a0) 149; RV64ZBA-NEXT: ret 150 %3 = getelementptr inbounds i32, ptr %1, i64 %0 151 %4 = load i32, ptr %3 152 ret i32 %4 153} 154 155define i64 @sh3add(i64 %0, ptr %1) { 156; RV64I-LABEL: sh3add: 157; RV64I: # %bb.0: 158; RV64I-NEXT: slli a0, a0, 3 159; RV64I-NEXT: add a0, a1, a0 160; RV64I-NEXT: ld a0, 0(a0) 161; RV64I-NEXT: ret 162; 163; RV64ZBA-LABEL: sh3add: 164; RV64ZBA: # %bb.0: 165; RV64ZBA-NEXT: sh3add a0, a0, a1 166; RV64ZBA-NEXT: ld a0, 0(a0) 167; RV64ZBA-NEXT: ret 168 %3 = getelementptr inbounds i64, ptr %1, i64 %0 169 %4 = load i64, ptr %3 170 ret i64 %4 171} 172 173define signext i16 @sh1adduw(i32 signext %0, ptr %1) { 174; RV64I-LABEL: sh1adduw: 175; RV64I: # %bb.0: 176; RV64I-NEXT: slli a0, a0, 32 177; RV64I-NEXT: srli a0, a0, 31 178; RV64I-NEXT: add a0, a1, a0 179; RV64I-NEXT: lh a0, 0(a0) 180; RV64I-NEXT: ret 181; 182; RV64ZBA-LABEL: sh1adduw: 183; RV64ZBA: # %bb.0: 184; RV64ZBA-NEXT: sh1add.uw a0, a0, a1 185; RV64ZBA-NEXT: lh a0, 0(a0) 186; RV64ZBA-NEXT: ret 187 %3 = zext i32 %0 to i64 188 %4 = getelementptr inbounds i16, ptr %1, i64 %3 189 %5 = load i16, ptr %4 190 ret i16 %5 191} 192 193define i64 @sh1adduw_2(i64 %0, i64 %1) { 194; RV64I-LABEL: sh1adduw_2: 195; RV64I: # %bb.0: 196; RV64I-NEXT: li a2, 1 197; RV64I-NEXT: slli a2, a2, 33 198; RV64I-NEXT: addi a2, a2, -2 199; RV64I-NEXT: slli a0, a0, 1 200; RV64I-NEXT: and a0, a0, a2 201; RV64I-NEXT: add a0, a0, a1 202; RV64I-NEXT: ret 203; 204; RV64ZBA-LABEL: sh1adduw_2: 205; RV64ZBA: # %bb.0: 206; RV64ZBA-NEXT: slli a0, a0, 1 207; RV64ZBA-NEXT: srli a0, a0, 1 208; RV64ZBA-NEXT: sh1add.uw a0, a0, a1 209; RV64ZBA-NEXT: ret 210 %3 = shl i64 %0, 1 211 %4 = and i64 %3, 8589934590 212 %5 = add i64 %4, %1 213 ret i64 %5 214} 215 216define i64 @sh1adduw_3(i64 %0, i64 %1) { 217; RV64I-LABEL: sh1adduw_3: 218; RV64I: # %bb.0: 219; RV64I-NEXT: li a2, 1 220; RV64I-NEXT: slli a2, a2, 33 221; RV64I-NEXT: addi a2, a2, -2 222; RV64I-NEXT: slli a0, a0, 1 223; RV64I-NEXT: and a0, a0, a2 224; RV64I-NEXT: or a0, a0, a1 225; RV64I-NEXT: ret 226; 227; RV64ZBA-LABEL: sh1adduw_3: 228; RV64ZBA: # %bb.0: 229; RV64ZBA-NEXT: slli a0, a0, 1 230; RV64ZBA-NEXT: srli a0, a0, 1 231; RV64ZBA-NEXT: slli.uw a0, a0, 1 232; RV64ZBA-NEXT: or a0, a0, a1 233; RV64ZBA-NEXT: ret 234 %3 = shl i64 %0, 1 235 %4 = and i64 %3, 8589934590 236 %5 = or disjoint i64 %4, %1 237 ret i64 %5 238} 239 240define signext i32 @sh2adduw(i32 signext %0, ptr %1) { 241; RV64I-LABEL: sh2adduw: 242; RV64I: # %bb.0: 243; RV64I-NEXT: slli a0, a0, 32 244; RV64I-NEXT: srli a0, a0, 30 245; RV64I-NEXT: add a0, a1, a0 246; RV64I-NEXT: lw a0, 0(a0) 247; RV64I-NEXT: ret 248; 249; RV64ZBA-LABEL: sh2adduw: 250; RV64ZBA: # %bb.0: 251; RV64ZBA-NEXT: sh2add.uw a0, a0, a1 252; RV64ZBA-NEXT: lw a0, 0(a0) 253; RV64ZBA-NEXT: ret 254 %3 = zext i32 %0 to i64 255 %4 = getelementptr inbounds i32, ptr %1, i64 %3 256 %5 = load i32, ptr %4 257 ret i32 %5 258} 259 260define i64 @sh2adduw_2(i64 %0, i64 %1) { 261; RV64I-LABEL: sh2adduw_2: 262; RV64I: # %bb.0: 263; RV64I-NEXT: li a2, 1 264; RV64I-NEXT: slli a2, a2, 34 265; RV64I-NEXT: addi a2, a2, -4 266; RV64I-NEXT: slli a0, a0, 2 267; RV64I-NEXT: and a0, a0, a2 268; RV64I-NEXT: add a0, a0, a1 269; RV64I-NEXT: ret 270; 271; RV64ZBA-LABEL: sh2adduw_2: 272; RV64ZBA: # %bb.0: 273; RV64ZBA-NEXT: slli a0, a0, 2 274; RV64ZBA-NEXT: srli a0, a0, 2 275; RV64ZBA-NEXT: sh2add.uw a0, a0, a1 276; RV64ZBA-NEXT: ret 277 %3 = shl i64 %0, 2 278 %4 = and i64 %3, 17179869180 279 %5 = add i64 %4, %1 280 ret i64 %5 281} 282 283define i64 @sh2adduw_3(i64 %0, i64 %1) { 284; RV64I-LABEL: sh2adduw_3: 285; RV64I: # %bb.0: 286; RV64I-NEXT: li a2, 1 287; RV64I-NEXT: slli a2, a2, 34 288; RV64I-NEXT: addi a2, a2, -4 289; RV64I-NEXT: slli a0, a0, 2 290; RV64I-NEXT: and a0, a0, a2 291; RV64I-NEXT: or a0, a0, a1 292; RV64I-NEXT: ret 293; 294; RV64ZBA-LABEL: sh2adduw_3: 295; RV64ZBA: # %bb.0: 296; RV64ZBA-NEXT: slli a0, a0, 2 297; RV64ZBA-NEXT: srli a0, a0, 2 298; RV64ZBA-NEXT: slli.uw a0, a0, 2 299; RV64ZBA-NEXT: or a0, a0, a1 300; RV64ZBA-NEXT: ret 301 %3 = shl i64 %0, 2 302 %4 = and i64 %3, 17179869180 303 %5 = or disjoint i64 %4, %1 304 ret i64 %5 305} 306 307define i64 @sh3adduw(i32 signext %0, ptr %1) { 308; RV64I-LABEL: sh3adduw: 309; RV64I: # %bb.0: 310; RV64I-NEXT: slli a0, a0, 32 311; RV64I-NEXT: srli a0, a0, 29 312; RV64I-NEXT: add a0, a1, a0 313; RV64I-NEXT: ld a0, 0(a0) 314; RV64I-NEXT: ret 315; 316; RV64ZBA-LABEL: sh3adduw: 317; RV64ZBA: # %bb.0: 318; RV64ZBA-NEXT: sh3add.uw a0, a0, a1 319; RV64ZBA-NEXT: ld a0, 0(a0) 320; RV64ZBA-NEXT: ret 321 %3 = zext i32 %0 to i64 322 %4 = getelementptr inbounds i64, ptr %1, i64 %3 323 %5 = load i64, ptr %4 324 ret i64 %5 325} 326 327define i64 @sh3adduw_2(i64 %0, i64 %1) { 328; RV64I-LABEL: sh3adduw_2: 329; RV64I: # %bb.0: 330; RV64I-NEXT: li a2, 1 331; RV64I-NEXT: slli a2, a2, 35 332; RV64I-NEXT: addi a2, a2, -8 333; RV64I-NEXT: slli a0, a0, 3 334; RV64I-NEXT: and a0, a0, a2 335; RV64I-NEXT: add a0, a0, a1 336; RV64I-NEXT: ret 337; 338; RV64ZBA-LABEL: sh3adduw_2: 339; RV64ZBA: # %bb.0: 340; RV64ZBA-NEXT: slli a0, a0, 3 341; RV64ZBA-NEXT: srli a0, a0, 3 342; RV64ZBA-NEXT: sh3add.uw a0, a0, a1 343; RV64ZBA-NEXT: ret 344 %3 = shl i64 %0, 3 345 %4 = and i64 %3, 34359738360 346 %5 = add i64 %4, %1 347 ret i64 %5 348} 349 350define i64 @sh3adduw_3(i64 %0, i64 %1) { 351; RV64I-LABEL: sh3adduw_3: 352; RV64I: # %bb.0: 353; RV64I-NEXT: li a2, 1 354; RV64I-NEXT: slli a2, a2, 35 355; RV64I-NEXT: addi a2, a2, -8 356; RV64I-NEXT: slli a0, a0, 3 357; RV64I-NEXT: and a0, a0, a2 358; RV64I-NEXT: or a0, a0, a1 359; RV64I-NEXT: ret 360; 361; RV64ZBA-LABEL: sh3adduw_3: 362; RV64ZBA: # %bb.0: 363; RV64ZBA-NEXT: slli a0, a0, 3 364; RV64ZBA-NEXT: srli a0, a0, 3 365; RV64ZBA-NEXT: slli.uw a0, a0, 3 366; RV64ZBA-NEXT: or a0, a0, a1 367; RV64ZBA-NEXT: ret 368 %3 = shl i64 %0, 3 369 %4 = and i64 %3, 34359738360 370 %5 = or disjoint i64 %4, %1 371 ret i64 %5 372} 373 374; Make sure we use sext.h+slli+srli for Zba+Zbb. 375; FIXME: The RV64I and Zba only cases can be done with only 3 shifts. 376define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind { 377; RV64I-LABEL: sext_ashr_zext_i8: 378; RV64I: # %bb.0: 379; RV64I-NEXT: slli a0, a0, 56 380; RV64I-NEXT: srai a0, a0, 63 381; RV64I-NEXT: slli a0, a0, 32 382; RV64I-NEXT: srli a0, a0, 32 383; RV64I-NEXT: ret 384; 385; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8: 386; RV64ZBANOZBB: # %bb.0: 387; RV64ZBANOZBB-NEXT: slli a0, a0, 56 388; RV64ZBANOZBB-NEXT: srai a0, a0, 63 389; RV64ZBANOZBB-NEXT: zext.w a0, a0 390; RV64ZBANOZBB-NEXT: ret 391; 392; RV64ZBAZBB-LABEL: sext_ashr_zext_i8: 393; RV64ZBAZBB: # %bb.0: 394; RV64ZBAZBB-NEXT: sext.b a0, a0 395; RV64ZBAZBB-NEXT: srai a0, a0, 9 396; RV64ZBAZBB-NEXT: zext.w a0, a0 397; RV64ZBAZBB-NEXT: ret 398 %ext = sext i8 %a to i32 399 %1 = ashr i32 %ext, 9 400 ret i32 %1 401} 402 403define i64 @sh6_sh3_add1(i64 noundef %x, i64 noundef %y, i64 noundef %z) { 404; RV64I-LABEL: sh6_sh3_add1: 405; RV64I: # %bb.0: # %entry 406; RV64I-NEXT: slli a2, a2, 3 407; RV64I-NEXT: slli a1, a1, 6 408; RV64I-NEXT: add a1, a1, a2 409; RV64I-NEXT: add a0, a1, a0 410; RV64I-NEXT: ret 411; 412; RV64ZBA-LABEL: sh6_sh3_add1: 413; RV64ZBA: # %bb.0: # %entry 414; RV64ZBA-NEXT: slli a1, a1, 6 415; RV64ZBA-NEXT: sh3add a1, a2, a1 416; RV64ZBA-NEXT: add a0, a1, a0 417; RV64ZBA-NEXT: ret 418entry: 419 %shl = shl i64 %z, 3 420 %shl1 = shl i64 %y, 6 421 %add = add nsw i64 %shl1, %shl 422 %add2 = add nsw i64 %add, %x 423 ret i64 %add2 424} 425 426define i64 @sh6_sh3_add2(i64 noundef %x, i64 noundef %y, i64 noundef %z) { 427; RV64I-LABEL: sh6_sh3_add2: 428; RV64I: # %bb.0: # %entry 429; RV64I-NEXT: slli a2, a2, 3 430; RV64I-NEXT: slli a1, a1, 6 431; RV64I-NEXT: add a0, a1, a0 432; RV64I-NEXT: add a0, a0, a2 433; RV64I-NEXT: ret 434; 435; RV64ZBA-LABEL: sh6_sh3_add2: 436; RV64ZBA: # %bb.0: # %entry 437; RV64ZBA-NEXT: sh3add a1, a1, a2 438; RV64ZBA-NEXT: sh3add a0, a1, a0 439; RV64ZBA-NEXT: ret 440entry: 441 %shl = shl i64 %z, 3 442 %shl1 = shl i64 %y, 6 443 %add = add nsw i64 %shl1, %x 444 %add2 = add nsw i64 %add, %shl 445 ret i64 %add2 446} 447 448define i64 @sh6_sh3_add3(i64 noundef %x, i64 noundef %y, i64 noundef %z) { 449; RV64I-LABEL: sh6_sh3_add3: 450; RV64I: # %bb.0: # %entry 451; RV64I-NEXT: slli a2, a2, 3 452; RV64I-NEXT: slli a1, a1, 6 453; RV64I-NEXT: add a1, a1, a2 454; RV64I-NEXT: add a0, a0, a1 455; RV64I-NEXT: ret 456; 457; RV64ZBA-LABEL: sh6_sh3_add3: 458; RV64ZBA: # %bb.0: # %entry 459; RV64ZBA-NEXT: slli a1, a1, 6 460; RV64ZBA-NEXT: sh3add a1, a2, a1 461; RV64ZBA-NEXT: add a0, a0, a1 462; RV64ZBA-NEXT: ret 463entry: 464 %shl = shl i64 %z, 3 465 %shl1 = shl i64 %y, 6 466 %add = add nsw i64 %shl1, %shl 467 %add2 = add nsw i64 %x, %add 468 ret i64 %add2 469} 470 471define i64 @sh6_sh3_add4(i64 noundef %x, i64 noundef %y, i64 noundef %z) { 472; RV64I-LABEL: sh6_sh3_add4: 473; RV64I: # %bb.0: # %entry 474; RV64I-NEXT: slli a2, a2, 3 475; RV64I-NEXT: slli a1, a1, 6 476; RV64I-NEXT: add a0, a0, a2 477; RV64I-NEXT: add a0, a0, a1 478; RV64I-NEXT: ret 479; 480; RV64ZBA-LABEL: sh6_sh3_add4: 481; RV64ZBA: # %bb.0: # %entry 482; RV64ZBA-NEXT: slli a1, a1, 6 483; RV64ZBA-NEXT: sh3add a0, a2, a0 484; RV64ZBA-NEXT: add a0, a0, a1 485; RV64ZBA-NEXT: ret 486entry: 487 %shl = shl i64 %z, 3 488 %shl1 = shl i64 %y, 6 489 %add = add nsw i64 %x, %shl 490 %add2 = add nsw i64 %add, %shl1 491 ret i64 %add2 492} 493 494; Make sure we use sext.h+slli+srli for Zba+Zbb. 495; FIXME: The RV64I and Zba only cases can be done with only 3 shifts. 496define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind { 497; RV64I-LABEL: sext_ashr_zext_i16: 498; RV64I: # %bb.0: 499; RV64I-NEXT: slli a0, a0, 48 500; RV64I-NEXT: srai a0, a0, 57 501; RV64I-NEXT: slli a0, a0, 32 502; RV64I-NEXT: srli a0, a0, 32 503; RV64I-NEXT: ret 504; 505; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16: 506; RV64ZBANOZBB: # %bb.0: 507; RV64ZBANOZBB-NEXT: slli a0, a0, 48 508; RV64ZBANOZBB-NEXT: srai a0, a0, 57 509; RV64ZBANOZBB-NEXT: zext.w a0, a0 510; RV64ZBANOZBB-NEXT: ret 511; 512; RV64ZBAZBB-LABEL: sext_ashr_zext_i16: 513; RV64ZBAZBB: # %bb.0: 514; RV64ZBAZBB-NEXT: sext.h a0, a0 515; RV64ZBAZBB-NEXT: srai a0, a0, 9 516; RV64ZBAZBB-NEXT: zext.w a0, a0 517; RV64ZBAZBB-NEXT: ret 518 %ext = sext i16 %a to i32 519 %1 = ashr i32 %ext, 9 520 ret i32 %1 521} 522 523; This the IR you get from InstCombine if take the difference of 2 pointers and 524; cast is to unsigned before using as an index. 525define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) { 526; RV64I-LABEL: sh1adduw_ptrdiff: 527; RV64I: # %bb.0: 528; RV64I-NEXT: srli a0, a0, 1 529; RV64I-NEXT: slli a0, a0, 32 530; RV64I-NEXT: srli a0, a0, 31 531; RV64I-NEXT: add a0, a1, a0 532; RV64I-NEXT: lh a0, 0(a0) 533; RV64I-NEXT: ret 534; 535; RV64ZBA-LABEL: sh1adduw_ptrdiff: 536; RV64ZBA: # %bb.0: 537; RV64ZBA-NEXT: srli a0, a0, 1 538; RV64ZBA-NEXT: sh1add.uw a0, a0, a1 539; RV64ZBA-NEXT: lh a0, 0(a0) 540; RV64ZBA-NEXT: ret 541 %ptrdiff = lshr exact i64 %diff, 1 542 %cast = and i64 %ptrdiff, 4294967295 543 %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast 544 %res = load i16, ptr %ptr 545 ret i16 %res 546} 547 548define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) { 549; RV64I-LABEL: sh2adduw_ptrdiff: 550; RV64I: # %bb.0: 551; RV64I-NEXT: srli a0, a0, 2 552; RV64I-NEXT: slli a0, a0, 32 553; RV64I-NEXT: srli a0, a0, 30 554; RV64I-NEXT: add a0, a1, a0 555; RV64I-NEXT: lw a0, 0(a0) 556; RV64I-NEXT: ret 557; 558; RV64ZBA-LABEL: sh2adduw_ptrdiff: 559; RV64ZBA: # %bb.0: 560; RV64ZBA-NEXT: srli a0, a0, 2 561; RV64ZBA-NEXT: sh2add.uw a0, a0, a1 562; RV64ZBA-NEXT: lw a0, 0(a0) 563; RV64ZBA-NEXT: ret 564 %ptrdiff = lshr exact i64 %diff, 2 565 %cast = and i64 %ptrdiff, 4294967295 566 %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast 567 %res = load i32, ptr %ptr 568 ret i32 %res 569} 570 571define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) { 572; RV64I-LABEL: sh3adduw_ptrdiff: 573; RV64I: # %bb.0: 574; RV64I-NEXT: srli a0, a0, 3 575; RV64I-NEXT: slli a0, a0, 32 576; RV64I-NEXT: srli a0, a0, 29 577; RV64I-NEXT: add a0, a1, a0 578; RV64I-NEXT: ld a0, 0(a0) 579; RV64I-NEXT: ret 580; 581; RV64ZBA-LABEL: sh3adduw_ptrdiff: 582; RV64ZBA: # %bb.0: 583; RV64ZBA-NEXT: srli a0, a0, 3 584; RV64ZBA-NEXT: sh3add.uw a0, a0, a1 585; RV64ZBA-NEXT: ld a0, 0(a0) 586; RV64ZBA-NEXT: ret 587 %ptrdiff = lshr exact i64 %diff, 3 588 %cast = and i64 %ptrdiff, 4294967295 589 %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast 590 %res = load i64, ptr %ptr 591 ret i64 %res 592} 593 594define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) { 595; RV64I-LABEL: srliw_1_sh1add: 596; RV64I: # %bb.0: 597; RV64I-NEXT: srliw a1, a1, 1 598; RV64I-NEXT: slli a1, a1, 1 599; RV64I-NEXT: add a0, a0, a1 600; RV64I-NEXT: lh a0, 0(a0) 601; RV64I-NEXT: ret 602; 603; RV64ZBA-LABEL: srliw_1_sh1add: 604; RV64ZBA: # %bb.0: 605; RV64ZBA-NEXT: srliw a1, a1, 1 606; RV64ZBA-NEXT: sh1add a0, a1, a0 607; RV64ZBA-NEXT: lh a0, 0(a0) 608; RV64ZBA-NEXT: ret 609 %3 = lshr i32 %1, 1 610 %4 = zext i32 %3 to i64 611 %5 = getelementptr inbounds i16, ptr %0, i64 %4 612 %6 = load i16, ptr %5, align 2 613 ret i16 %6 614} 615 616define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) { 617; RV64I-LABEL: slliuw_ptrdiff: 618; RV64I: # %bb.0: 619; RV64I-NEXT: srli a0, a0, 4 620; RV64I-NEXT: slli a0, a0, 32 621; RV64I-NEXT: srli a0, a0, 28 622; RV64I-NEXT: add a1, a1, a0 623; RV64I-NEXT: ld a0, 0(a1) 624; RV64I-NEXT: ld a1, 8(a1) 625; RV64I-NEXT: ret 626; 627; RV64ZBA-LABEL: slliuw_ptrdiff: 628; RV64ZBA: # %bb.0: 629; RV64ZBA-NEXT: srli a0, a0, 4 630; RV64ZBA-NEXT: slli.uw a0, a0, 4 631; RV64ZBA-NEXT: add a1, a1, a0 632; RV64ZBA-NEXT: ld a0, 0(a1) 633; RV64ZBA-NEXT: ld a1, 8(a1) 634; RV64ZBA-NEXT: ret 635 %ptrdiff = lshr exact i64 %diff, 4 636 %cast = and i64 %ptrdiff, 4294967295 637 %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast 638 %res = load i128, ptr %ptr 639 ret i128 %res 640} 641 642define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) { 643; RV64I-LABEL: srliw_2_sh2add: 644; RV64I: # %bb.0: 645; RV64I-NEXT: srliw a1, a1, 2 646; RV64I-NEXT: slli a1, a1, 2 647; RV64I-NEXT: add a0, a0, a1 648; RV64I-NEXT: lw a0, 0(a0) 649; RV64I-NEXT: ret 650; 651; RV64ZBA-LABEL: srliw_2_sh2add: 652; RV64ZBA: # %bb.0: 653; RV64ZBA-NEXT: srliw a1, a1, 2 654; RV64ZBA-NEXT: sh2add a0, a1, a0 655; RV64ZBA-NEXT: lw a0, 0(a0) 656; RV64ZBA-NEXT: ret 657 %3 = lshr i32 %1, 2 658 %4 = zext i32 %3 to i64 659 %5 = getelementptr inbounds i32, ptr %0, i64 %4 660 %6 = load i32, ptr %5, align 4 661 ret i32 %6 662} 663 664define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) { 665; RV64I-LABEL: srliw_3_sh3add: 666; RV64I: # %bb.0: 667; RV64I-NEXT: srliw a1, a1, 3 668; RV64I-NEXT: slli a1, a1, 3 669; RV64I-NEXT: add a0, a0, a1 670; RV64I-NEXT: ld a0, 0(a0) 671; RV64I-NEXT: ret 672; 673; RV64ZBA-LABEL: srliw_3_sh3add: 674; RV64ZBA: # %bb.0: 675; RV64ZBA-NEXT: srliw a1, a1, 3 676; RV64ZBA-NEXT: sh3add a0, a1, a0 677; RV64ZBA-NEXT: ld a0, 0(a0) 678; RV64ZBA-NEXT: ret 679 %3 = lshr i32 %1, 3 680 %4 = zext i32 %3 to i64 681 %5 = getelementptr inbounds i64, ptr %0, i64 %4 682 %6 = load i64, ptr %5, align 8 683 ret i64 %6 684} 685 686define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) { 687; RV64I-LABEL: srliw_1_sh2add: 688; RV64I: # %bb.0: 689; RV64I-NEXT: srliw a1, a1, 1 690; RV64I-NEXT: slli a1, a1, 2 691; RV64I-NEXT: add a0, a0, a1 692; RV64I-NEXT: lw a0, 0(a0) 693; RV64I-NEXT: ret 694; 695; RV64ZBA-LABEL: srliw_1_sh2add: 696; RV64ZBA: # %bb.0: 697; RV64ZBA-NEXT: srliw a1, a1, 1 698; RV64ZBA-NEXT: sh2add a0, a1, a0 699; RV64ZBA-NEXT: lw a0, 0(a0) 700; RV64ZBA-NEXT: ret 701 %3 = lshr i32 %1, 1 702 %4 = zext i32 %3 to i64 703 %5 = getelementptr inbounds i32, ptr %0, i64 %4 704 %6 = load i32, ptr %5, align 4 705 ret i32 %6 706} 707 708define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) { 709; RV64I-LABEL: srliw_1_sh3add: 710; RV64I: # %bb.0: 711; RV64I-NEXT: srliw a1, a1, 1 712; RV64I-NEXT: slli a1, a1, 3 713; RV64I-NEXT: add a0, a0, a1 714; RV64I-NEXT: ld a0, 0(a0) 715; RV64I-NEXT: ret 716; 717; RV64ZBA-LABEL: srliw_1_sh3add: 718; RV64ZBA: # %bb.0: 719; RV64ZBA-NEXT: srliw a1, a1, 1 720; RV64ZBA-NEXT: sh3add a0, a1, a0 721; RV64ZBA-NEXT: ld a0, 0(a0) 722; RV64ZBA-NEXT: ret 723 %3 = lshr i32 %1, 1 724 %4 = zext i32 %3 to i64 725 %5 = getelementptr inbounds i64, ptr %0, i64 %4 726 %6 = load i64, ptr %5, align 8 727 ret i64 %6 728} 729 730define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) { 731; RV64I-LABEL: srliw_2_sh3add: 732; RV64I: # %bb.0: 733; RV64I-NEXT: srliw a1, a1, 2 734; RV64I-NEXT: slli a1, a1, 3 735; RV64I-NEXT: add a0, a0, a1 736; RV64I-NEXT: ld a0, 0(a0) 737; RV64I-NEXT: ret 738; 739; RV64ZBA-LABEL: srliw_2_sh3add: 740; RV64ZBA: # %bb.0: 741; RV64ZBA-NEXT: srliw a1, a1, 2 742; RV64ZBA-NEXT: sh3add a0, a1, a0 743; RV64ZBA-NEXT: ld a0, 0(a0) 744; RV64ZBA-NEXT: ret 745 %3 = lshr i32 %1, 2 746 %4 = zext i32 %3 to i64 747 %5 = getelementptr inbounds i64, ptr %0, i64 %4 748 %6 = load i64, ptr %5, align 8 749 ret i64 %6 750} 751 752define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) { 753; RV64I-LABEL: srliw_2_sh1add: 754; RV64I: # %bb.0: 755; RV64I-NEXT: srliw a1, a1, 2 756; RV64I-NEXT: slli a1, a1, 1 757; RV64I-NEXT: add a0, a0, a1 758; RV64I-NEXT: lh a0, 0(a0) 759; RV64I-NEXT: ret 760; 761; RV64ZBA-LABEL: srliw_2_sh1add: 762; RV64ZBA: # %bb.0: 763; RV64ZBA-NEXT: srliw a1, a1, 2 764; RV64ZBA-NEXT: sh1add a0, a1, a0 765; RV64ZBA-NEXT: lh a0, 0(a0) 766; RV64ZBA-NEXT: ret 767 %3 = lshr i32 %1, 2 768 %4 = zext i32 %3 to i64 769 %5 = getelementptr inbounds i16, ptr %0, i64 %4 770 %6 = load i16, ptr %5, align 2 771 ret i16 %6 772} 773 774 775define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) { 776; RV64I-LABEL: srliw_3_sh2add: 777; RV64I: # %bb.0: 778; RV64I-NEXT: srliw a1, a1, 3 779; RV64I-NEXT: slli a1, a1, 2 780; RV64I-NEXT: add a0, a0, a1 781; RV64I-NEXT: lw a0, 0(a0) 782; RV64I-NEXT: ret 783; 784; RV64ZBA-LABEL: srliw_3_sh2add: 785; RV64ZBA: # %bb.0: 786; RV64ZBA-NEXT: srliw a1, a1, 3 787; RV64ZBA-NEXT: sh2add a0, a1, a0 788; RV64ZBA-NEXT: lw a0, 0(a0) 789; RV64ZBA-NEXT: ret 790 %3 = lshr i32 %1, 3 791 %4 = zext i32 %3 to i64 792 %5 = getelementptr inbounds i32, ptr %0, i64 %4 793 %6 = load i32, ptr %5, align 4 794 ret i32 %6 795} 796 797define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) { 798; RV64I-LABEL: srliw_4_sh3add: 799; RV64I: # %bb.0: 800; RV64I-NEXT: srliw a1, a1, 4 801; RV64I-NEXT: slli a1, a1, 3 802; RV64I-NEXT: add a0, a0, a1 803; RV64I-NEXT: ld a0, 0(a0) 804; RV64I-NEXT: ret 805; 806; RV64ZBA-LABEL: srliw_4_sh3add: 807; RV64ZBA: # %bb.0: 808; RV64ZBA-NEXT: srliw a1, a1, 4 809; RV64ZBA-NEXT: sh3add a0, a1, a0 810; RV64ZBA-NEXT: ld a0, 0(a0) 811; RV64ZBA-NEXT: ret 812 %3 = lshr i32 %1, 4 813 %4 = zext i32 %3 to i64 814 %5 = getelementptr inbounds i64, ptr %0, i64 %4 815 %6 = load i64, ptr %5, align 8 816 ret i64 %6 817} 818 819define signext i32 @srli_1_sh2add(ptr %0, i64 %1) { 820; RV64I-LABEL: srli_1_sh2add: 821; RV64I: # %bb.0: 822; RV64I-NEXT: srli a1, a1, 1 823; RV64I-NEXT: slli a1, a1, 2 824; RV64I-NEXT: add a0, a0, a1 825; RV64I-NEXT: lw a0, 0(a0) 826; RV64I-NEXT: ret 827; 828; RV64ZBA-LABEL: srli_1_sh2add: 829; RV64ZBA: # %bb.0: 830; RV64ZBA-NEXT: srli a1, a1, 1 831; RV64ZBA-NEXT: sh2add a0, a1, a0 832; RV64ZBA-NEXT: lw a0, 0(a0) 833; RV64ZBA-NEXT: ret 834 %3 = lshr i64 %1, 1 835 %4 = getelementptr inbounds i32, ptr %0, i64 %3 836 %5 = load i32, ptr %4, align 4 837 ret i32 %5 838} 839 840define i64 @srli_2_sh3add(ptr %0, i64 %1) { 841; RV64I-LABEL: srli_2_sh3add: 842; RV64I: # %bb.0: 843; RV64I-NEXT: srli a1, a1, 2 844; RV64I-NEXT: slli a1, a1, 3 845; RV64I-NEXT: add a0, a0, a1 846; RV64I-NEXT: ld a0, 0(a0) 847; RV64I-NEXT: ret 848; 849; RV64ZBA-LABEL: srli_2_sh3add: 850; RV64ZBA: # %bb.0: 851; RV64ZBA-NEXT: srli a1, a1, 2 852; RV64ZBA-NEXT: sh3add a0, a1, a0 853; RV64ZBA-NEXT: ld a0, 0(a0) 854; RV64ZBA-NEXT: ret 855 %3 = lshr i64 %1, 2 856 %4 = getelementptr inbounds i64, ptr %0, i64 %3 857 %5 = load i64, ptr %4, align 8 858 ret i64 %5 859} 860 861define signext i16 @srli_2_sh1add(ptr %0, i64 %1) { 862; RV64I-LABEL: srli_2_sh1add: 863; RV64I: # %bb.0: 864; RV64I-NEXT: srli a1, a1, 2 865; RV64I-NEXT: slli a1, a1, 1 866; RV64I-NEXT: add a0, a0, a1 867; RV64I-NEXT: lh a0, 0(a0) 868; RV64I-NEXT: ret 869; 870; RV64ZBA-LABEL: srli_2_sh1add: 871; RV64ZBA: # %bb.0: 872; RV64ZBA-NEXT: srli a1, a1, 2 873; RV64ZBA-NEXT: sh1add a0, a1, a0 874; RV64ZBA-NEXT: lh a0, 0(a0) 875; RV64ZBA-NEXT: ret 876 %3 = lshr i64 %1, 2 877 %4 = getelementptr inbounds i16, ptr %0, i64 %3 878 %5 = load i16, ptr %4, align 2 879 ret i16 %5 880} 881 882define signext i32 @srli_3_sh2add(ptr %0, i64 %1) { 883; RV64I-LABEL: srli_3_sh2add: 884; RV64I: # %bb.0: 885; RV64I-NEXT: srli a1, a1, 3 886; RV64I-NEXT: slli a1, a1, 2 887; RV64I-NEXT: add a0, a0, a1 888; RV64I-NEXT: lw a0, 0(a0) 889; RV64I-NEXT: ret 890; 891; RV64ZBA-LABEL: srli_3_sh2add: 892; RV64ZBA: # %bb.0: 893; RV64ZBA-NEXT: srli a1, a1, 3 894; RV64ZBA-NEXT: sh2add a0, a1, a0 895; RV64ZBA-NEXT: lw a0, 0(a0) 896; RV64ZBA-NEXT: ret 897 %3 = lshr i64 %1, 3 898 %4 = getelementptr inbounds i32, ptr %0, i64 %3 899 %5 = load i32, ptr %4, align 4 900 ret i32 %5 901} 902 903define i64 @srli_4_sh3add(ptr %0, i64 %1) { 904; RV64I-LABEL: srli_4_sh3add: 905; RV64I: # %bb.0: 906; RV64I-NEXT: srli a1, a1, 4 907; RV64I-NEXT: slli a1, a1, 3 908; RV64I-NEXT: add a0, a0, a1 909; RV64I-NEXT: ld a0, 0(a0) 910; RV64I-NEXT: ret 911; 912; RV64ZBA-LABEL: srli_4_sh3add: 913; RV64ZBA: # %bb.0: 914; RV64ZBA-NEXT: srli a1, a1, 4 915; RV64ZBA-NEXT: sh3add a0, a1, a0 916; RV64ZBA-NEXT: ld a0, 0(a0) 917; RV64ZBA-NEXT: ret 918 %3 = lshr i64 %1, 4 919 %4 = getelementptr inbounds i64, ptr %0, i64 %3 920 %5 = load i64, ptr %4, align 8 921 ret i64 %5 922} 923 924define signext i16 @shl_2_sh1adduw(ptr %0, i32 signext %1) { 925; RV64I-LABEL: shl_2_sh1adduw: 926; RV64I: # %bb.0: 927; RV64I-NEXT: slli a1, a1, 2 928; RV64I-NEXT: slli a1, a1, 32 929; RV64I-NEXT: srli a1, a1, 31 930; RV64I-NEXT: add a0, a0, a1 931; RV64I-NEXT: lh a0, 0(a0) 932; RV64I-NEXT: ret 933; 934; RV64ZBA-LABEL: shl_2_sh1adduw: 935; RV64ZBA: # %bb.0: 936; RV64ZBA-NEXT: slli a1, a1, 2 937; RV64ZBA-NEXT: sh1add.uw a0, a1, a0 938; RV64ZBA-NEXT: lh a0, 0(a0) 939; RV64ZBA-NEXT: ret 940 %3 = shl i32 %1, 2 941 %4 = zext i32 %3 to i64 942 %5 = getelementptr inbounds i16, ptr %0, i64 %4 943 %6 = load i16, ptr %5, align 2 944 ret i16 %6 945} 946 947define signext i32 @shl_16_sh2adduw(ptr %0, i32 signext %1) { 948; RV64I-LABEL: shl_16_sh2adduw: 949; RV64I: # %bb.0: 950; RV64I-NEXT: slli a1, a1, 16 951; RV64I-NEXT: slli a1, a1, 32 952; RV64I-NEXT: srli a1, a1, 30 953; RV64I-NEXT: add a0, a0, a1 954; RV64I-NEXT: lw a0, 0(a0) 955; RV64I-NEXT: ret 956; 957; RV64ZBA-LABEL: shl_16_sh2adduw: 958; RV64ZBA: # %bb.0: 959; RV64ZBA-NEXT: slli a1, a1, 16 960; RV64ZBA-NEXT: sh2add.uw a0, a1, a0 961; RV64ZBA-NEXT: lw a0, 0(a0) 962; RV64ZBA-NEXT: ret 963 %3 = shl i32 %1, 16 964 %4 = zext i32 %3 to i64 965 %5 = getelementptr inbounds i32, ptr %0, i64 %4 966 %6 = load i32, ptr %5, align 4 967 ret i32 %6 968} 969 970define i64 @shl_31_sh3adduw(ptr %0, i32 signext %1) { 971; RV64I-LABEL: shl_31_sh3adduw: 972; RV64I: # %bb.0: 973; RV64I-NEXT: slli a1, a1, 31 974; RV64I-NEXT: slli a1, a1, 32 975; RV64I-NEXT: srli a1, a1, 29 976; RV64I-NEXT: add a0, a0, a1 977; RV64I-NEXT: ld a0, 0(a0) 978; RV64I-NEXT: ret 979; 980; RV64ZBA-LABEL: shl_31_sh3adduw: 981; RV64ZBA: # %bb.0: 982; RV64ZBA-NEXT: slli a1, a1, 31 983; RV64ZBA-NEXT: sh3add.uw a0, a1, a0 984; RV64ZBA-NEXT: ld a0, 0(a0) 985; RV64ZBA-NEXT: ret 986 %3 = shl i32 %1, 31 987 %4 = zext i32 %3 to i64 988 %5 = getelementptr inbounds i64, ptr %0, i64 %4 989 %6 = load i64, ptr %5, align 8 990 ret i64 %6 991} 992 993define i64 @pack_i64(i64 %a, i64 %b) nounwind { 994; RV64I-LABEL: pack_i64: 995; RV64I: # %bb.0: 996; RV64I-NEXT: slli a0, a0, 32 997; RV64I-NEXT: srli a0, a0, 32 998; RV64I-NEXT: slli a1, a1, 32 999; RV64I-NEXT: or a0, a1, a0 1000; RV64I-NEXT: ret 1001; 1002; RV64ZBA-LABEL: pack_i64: 1003; RV64ZBA: # %bb.0: 1004; RV64ZBA-NEXT: zext.w a0, a0 1005; RV64ZBA-NEXT: slli a1, a1, 32 1006; RV64ZBA-NEXT: or a0, a1, a0 1007; RV64ZBA-NEXT: ret 1008 %shl = and i64 %a, 4294967295 1009 %shl1 = shl i64 %b, 32 1010 %or = or i64 %shl1, %shl 1011 ret i64 %or 1012} 1013 1014define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind { 1015; RV64I-LABEL: pack_i64_2: 1016; RV64I: # %bb.0: 1017; RV64I-NEXT: slli a0, a0, 32 1018; RV64I-NEXT: slli a1, a1, 32 1019; RV64I-NEXT: srli a0, a0, 32 1020; RV64I-NEXT: srli a1, a1, 32 1021; RV64I-NEXT: slli a1, a1, 32 1022; RV64I-NEXT: or a0, a1, a0 1023; RV64I-NEXT: ret 1024; 1025; RV64ZBA-LABEL: pack_i64_2: 1026; RV64ZBA: # %bb.0: 1027; RV64ZBA-NEXT: zext.w a0, a0 1028; RV64ZBA-NEXT: zext.w a1, a1 1029; RV64ZBA-NEXT: slli a1, a1, 32 1030; RV64ZBA-NEXT: or a0, a1, a0 1031; RV64ZBA-NEXT: ret 1032 %zexta = zext i32 %a to i64 1033 %zextb = zext i32 %b to i64 1034 %shl1 = shl i64 %zextb, 32 1035 %or = or i64 %shl1, %zexta 1036 ret i64 %or 1037} 1038 1039define i64 @pack_i64_disjoint(i64 %a, i64 %b) nounwind { 1040; RV64I-LABEL: pack_i64_disjoint: 1041; RV64I: # %bb.0: 1042; RV64I-NEXT: slli a0, a0, 32 1043; RV64I-NEXT: srli a0, a0, 32 1044; RV64I-NEXT: or a0, a1, a0 1045; RV64I-NEXT: ret 1046; 1047; RV64ZBA-LABEL: pack_i64_disjoint: 1048; RV64ZBA: # %bb.0: 1049; RV64ZBA-NEXT: zext.w a0, a0 1050; RV64ZBA-NEXT: or a0, a1, a0 1051; RV64ZBA-NEXT: ret 1052 %shl = and i64 %a, 4294967295 1053 %or = or disjoint i64 %b, %shl 1054 ret i64 %or 1055} 1056 1057define i64 @pack_i64_disjoint_2(i32 signext %a, i64 %b) nounwind { 1058; RV64I-LABEL: pack_i64_disjoint_2: 1059; RV64I: # %bb.0: 1060; RV64I-NEXT: slli a0, a0, 32 1061; RV64I-NEXT: srli a0, a0, 32 1062; RV64I-NEXT: or a0, a1, a0 1063; RV64I-NEXT: ret 1064; 1065; RV64ZBA-LABEL: pack_i64_disjoint_2: 1066; RV64ZBA: # %bb.0: 1067; RV64ZBA-NEXT: zext.w a0, a0 1068; RV64ZBA-NEXT: or a0, a1, a0 1069; RV64ZBA-NEXT: ret 1070 %zexta = zext i32 %a to i64 1071 %or = or disjoint i64 %b, %zexta 1072 ret i64 %or 1073} 1074 1075define i8 @array_index_sh1_sh0(ptr %p, i64 %idx1, i64 %idx2) { 1076; RV64I-LABEL: array_index_sh1_sh0: 1077; RV64I: # %bb.0: 1078; RV64I-NEXT: slli a1, a1, 1 1079; RV64I-NEXT: add a0, a0, a2 1080; RV64I-NEXT: add a0, a0, a1 1081; RV64I-NEXT: lbu a0, 0(a0) 1082; RV64I-NEXT: ret 1083; 1084; RV64ZBA-LABEL: array_index_sh1_sh0: 1085; RV64ZBA: # %bb.0: 1086; RV64ZBA-NEXT: sh1add a0, a1, a0 1087; RV64ZBA-NEXT: add a0, a0, a2 1088; RV64ZBA-NEXT: lbu a0, 0(a0) 1089; RV64ZBA-NEXT: ret 1090 %a = getelementptr inbounds [2 x i8], ptr %p, i64 %idx1, i64 %idx2 1091 %b = load i8, ptr %a, align 1 1092 ret i8 %b 1093} 1094 1095define i16 @array_index_sh1_sh1(ptr %p, i64 %idx1, i64 %idx2) { 1096; RV64I-LABEL: array_index_sh1_sh1: 1097; RV64I: # %bb.0: 1098; RV64I-NEXT: slli a1, a1, 2 1099; RV64I-NEXT: add a0, a0, a1 1100; RV64I-NEXT: slli a2, a2, 1 1101; RV64I-NEXT: add a0, a0, a2 1102; RV64I-NEXT: lh a0, 0(a0) 1103; RV64I-NEXT: ret 1104; 1105; RV64ZBA-LABEL: array_index_sh1_sh1: 1106; RV64ZBA: # %bb.0: 1107; RV64ZBA-NEXT: sh2add a0, a1, a0 1108; RV64ZBA-NEXT: sh1add a0, a2, a0 1109; RV64ZBA-NEXT: lh a0, 0(a0) 1110; RV64ZBA-NEXT: ret 1111 %a = getelementptr inbounds [2 x i16], ptr %p, i64 %idx1, i64 %idx2 1112 %b = load i16, ptr %a, align 2 1113 ret i16 %b 1114} 1115 1116define i32 @array_index_sh1_sh2(ptr %p, i64 %idx1, i64 %idx2) { 1117; RV64I-LABEL: array_index_sh1_sh2: 1118; RV64I: # %bb.0: 1119; RV64I-NEXT: slli a1, a1, 3 1120; RV64I-NEXT: add a0, a0, a1 1121; RV64I-NEXT: slli a2, a2, 2 1122; RV64I-NEXT: add a0, a0, a2 1123; RV64I-NEXT: lw a0, 0(a0) 1124; RV64I-NEXT: ret 1125; 1126; RV64ZBA-LABEL: array_index_sh1_sh2: 1127; RV64ZBA: # %bb.0: 1128; RV64ZBA-NEXT: sh3add a0, a1, a0 1129; RV64ZBA-NEXT: sh2add a0, a2, a0 1130; RV64ZBA-NEXT: lw a0, 0(a0) 1131; RV64ZBA-NEXT: ret 1132 %a = getelementptr inbounds [2 x i32], ptr %p, i64 %idx1, i64 %idx2 1133 %b = load i32, ptr %a, align 4 1134 ret i32 %b 1135} 1136 1137define i64 @array_index_sh1_sh3(ptr %p, i64 %idx1, i64 %idx2) { 1138; RV64I-LABEL: array_index_sh1_sh3: 1139; RV64I: # %bb.0: 1140; RV64I-NEXT: slli a1, a1, 4 1141; RV64I-NEXT: add a0, a0, a1 1142; RV64I-NEXT: slli a2, a2, 3 1143; RV64I-NEXT: add a0, a0, a2 1144; RV64I-NEXT: ld a0, 0(a0) 1145; RV64I-NEXT: ret 1146; 1147; RV64ZBA-LABEL: array_index_sh1_sh3: 1148; RV64ZBA: # %bb.0: 1149; RV64ZBA-NEXT: sh1add a1, a1, a2 1150; RV64ZBA-NEXT: sh3add a0, a1, a0 1151; RV64ZBA-NEXT: ld a0, 0(a0) 1152; RV64ZBA-NEXT: ret 1153 %a = getelementptr inbounds [2 x i64], ptr %p, i64 %idx1, i64 %idx2 1154 %b = load i64, ptr %a, align 8 1155 ret i64 %b 1156} 1157 1158define i8 @array_index_sh2_sh0(ptr %p, i64 %idx1, i64 %idx2) { 1159; RV64I-LABEL: array_index_sh2_sh0: 1160; RV64I: # %bb.0: 1161; RV64I-NEXT: slli a1, a1, 2 1162; RV64I-NEXT: add a0, a0, a2 1163; RV64I-NEXT: add a0, a0, a1 1164; RV64I-NEXT: lbu a0, 0(a0) 1165; RV64I-NEXT: ret 1166; 1167; RV64ZBA-LABEL: array_index_sh2_sh0: 1168; RV64ZBA: # %bb.0: 1169; RV64ZBA-NEXT: sh2add a0, a1, a0 1170; RV64ZBA-NEXT: add a0, a0, a2 1171; RV64ZBA-NEXT: lbu a0, 0(a0) 1172; RV64ZBA-NEXT: ret 1173 %a = getelementptr inbounds [4 x i8], ptr %p, i64 %idx1, i64 %idx2 1174 %b = load i8, ptr %a, align 1 1175 ret i8 %b 1176} 1177 1178define i16 @array_index_sh2_sh1(ptr %p, i64 %idx1, i64 %idx2) { 1179; RV64I-LABEL: array_index_sh2_sh1: 1180; RV64I: # %bb.0: 1181; RV64I-NEXT: slli a1, a1, 3 1182; RV64I-NEXT: add a0, a0, a1 1183; RV64I-NEXT: slli a2, a2, 1 1184; RV64I-NEXT: add a0, a0, a2 1185; RV64I-NEXT: lh a0, 0(a0) 1186; RV64I-NEXT: ret 1187; 1188; RV64ZBA-LABEL: array_index_sh2_sh1: 1189; RV64ZBA: # %bb.0: 1190; RV64ZBA-NEXT: sh3add a0, a1, a0 1191; RV64ZBA-NEXT: sh1add a0, a2, a0 1192; RV64ZBA-NEXT: lh a0, 0(a0) 1193; RV64ZBA-NEXT: ret 1194 %a = getelementptr inbounds [4 x i16], ptr %p, i64 %idx1, i64 %idx2 1195 %b = load i16, ptr %a, align 2 1196 ret i16 %b 1197} 1198 1199define i32 @array_index_sh2_sh2(ptr %p, i64 %idx1, i64 %idx2) { 1200; RV64I-LABEL: array_index_sh2_sh2: 1201; RV64I: # %bb.0: 1202; RV64I-NEXT: slli a1, a1, 4 1203; RV64I-NEXT: add a0, a0, a1 1204; RV64I-NEXT: slli a2, a2, 2 1205; RV64I-NEXT: add a0, a0, a2 1206; RV64I-NEXT: lw a0, 0(a0) 1207; RV64I-NEXT: ret 1208; 1209; RV64ZBA-LABEL: array_index_sh2_sh2: 1210; RV64ZBA: # %bb.0: 1211; RV64ZBA-NEXT: sh2add a1, a1, a2 1212; RV64ZBA-NEXT: sh2add a0, a1, a0 1213; RV64ZBA-NEXT: lw a0, 0(a0) 1214; RV64ZBA-NEXT: ret 1215 %a = getelementptr inbounds [4 x i32], ptr %p, i64 %idx1, i64 %idx2 1216 %b = load i32, ptr %a, align 4 1217 ret i32 %b 1218} 1219 1220define i64 @array_index_sh2_sh3(ptr %p, i64 %idx1, i64 %idx2) { 1221; RV64I-LABEL: array_index_sh2_sh3: 1222; RV64I: # %bb.0: 1223; RV64I-NEXT: slli a1, a1, 5 1224; RV64I-NEXT: add a0, a0, a1 1225; RV64I-NEXT: slli a2, a2, 3 1226; RV64I-NEXT: add a0, a0, a2 1227; RV64I-NEXT: ld a0, 0(a0) 1228; RV64I-NEXT: ret 1229; 1230; RV64ZBA-LABEL: array_index_sh2_sh3: 1231; RV64ZBA: # %bb.0: 1232; RV64ZBA-NEXT: sh2add a1, a1, a2 1233; RV64ZBA-NEXT: sh3add a0, a1, a0 1234; RV64ZBA-NEXT: ld a0, 0(a0) 1235; RV64ZBA-NEXT: ret 1236 %a = getelementptr inbounds [4 x i64], ptr %p, i64 %idx1, i64 %idx2 1237 %b = load i64, ptr %a, align 8 1238 ret i64 %b 1239} 1240 1241define i8 @array_index_sh3_sh0(ptr %p, i64 %idx1, i64 %idx2) { 1242; RV64I-LABEL: array_index_sh3_sh0: 1243; RV64I: # %bb.0: 1244; RV64I-NEXT: slli a1, a1, 3 1245; RV64I-NEXT: add a0, a0, a2 1246; RV64I-NEXT: add a0, a0, a1 1247; RV64I-NEXT: lbu a0, 0(a0) 1248; RV64I-NEXT: ret 1249; 1250; RV64ZBA-LABEL: array_index_sh3_sh0: 1251; RV64ZBA: # %bb.0: 1252; RV64ZBA-NEXT: sh3add a0, a1, a0 1253; RV64ZBA-NEXT: add a0, a0, a2 1254; RV64ZBA-NEXT: lbu a0, 0(a0) 1255; RV64ZBA-NEXT: ret 1256 %a = getelementptr inbounds [8 x i8], ptr %p, i64 %idx1, i64 %idx2 1257 %b = load i8, ptr %a, align 1 1258 ret i8 %b 1259} 1260 1261define i16 @array_index_sh3_sh1(ptr %p, i64 %idx1, i64 %idx2) { 1262; RV64I-LABEL: array_index_sh3_sh1: 1263; RV64I: # %bb.0: 1264; RV64I-NEXT: slli a1, a1, 4 1265; RV64I-NEXT: add a0, a0, a1 1266; RV64I-NEXT: slli a2, a2, 1 1267; RV64I-NEXT: add a0, a0, a2 1268; RV64I-NEXT: lh a0, 0(a0) 1269; RV64I-NEXT: ret 1270; 1271; RV64ZBA-LABEL: array_index_sh3_sh1: 1272; RV64ZBA: # %bb.0: 1273; RV64ZBA-NEXT: sh3add a1, a1, a2 1274; RV64ZBA-NEXT: sh1add a0, a1, a0 1275; RV64ZBA-NEXT: lh a0, 0(a0) 1276; RV64ZBA-NEXT: ret 1277 %a = getelementptr inbounds [8 x i16], ptr %p, i64 %idx1, i64 %idx2 1278 %b = load i16, ptr %a, align 2 1279 ret i16 %b 1280} 1281 1282define i32 @array_index_sh3_sh2(ptr %p, i64 %idx1, i64 %idx2) { 1283; RV64I-LABEL: array_index_sh3_sh2: 1284; RV64I: # %bb.0: 1285; RV64I-NEXT: slli a1, a1, 5 1286; RV64I-NEXT: add a0, a0, a1 1287; RV64I-NEXT: slli a2, a2, 2 1288; RV64I-NEXT: add a0, a0, a2 1289; RV64I-NEXT: lw a0, 0(a0) 1290; RV64I-NEXT: ret 1291; 1292; RV64ZBA-LABEL: array_index_sh3_sh2: 1293; RV64ZBA: # %bb.0: 1294; RV64ZBA-NEXT: sh3add a1, a1, a2 1295; RV64ZBA-NEXT: sh2add a0, a1, a0 1296; RV64ZBA-NEXT: lw a0, 0(a0) 1297; RV64ZBA-NEXT: ret 1298 %a = getelementptr inbounds [8 x i32], ptr %p, i64 %idx1, i64 %idx2 1299 %b = load i32, ptr %a, align 4 1300 ret i32 %b 1301} 1302 1303define i64 @array_index_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) { 1304; RV64I-LABEL: array_index_sh3_sh3: 1305; RV64I: # %bb.0: 1306; RV64I-NEXT: slli a1, a1, 6 1307; RV64I-NEXT: add a0, a0, a1 1308; RV64I-NEXT: slli a2, a2, 3 1309; RV64I-NEXT: add a0, a0, a2 1310; RV64I-NEXT: ld a0, 0(a0) 1311; RV64I-NEXT: ret 1312; 1313; RV64ZBA-LABEL: array_index_sh3_sh3: 1314; RV64ZBA: # %bb.0: 1315; RV64ZBA-NEXT: sh3add a1, a1, a2 1316; RV64ZBA-NEXT: sh3add a0, a1, a0 1317; RV64ZBA-NEXT: ld a0, 0(a0) 1318; RV64ZBA-NEXT: ret 1319 %a = getelementptr inbounds [8 x i64], ptr %p, i64 %idx1, i64 %idx2 1320 %b = load i64, ptr %a, align 8 1321 ret i64 %b 1322} 1323 1324; Similar to above, but with a lshr on one of the indices. This requires 1325; special handling during isel to form a shift pair. 1326define i64 @array_index_lshr_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) { 1327; RV64I-LABEL: array_index_lshr_sh3_sh3: 1328; RV64I: # %bb.0: 1329; RV64I-NEXT: srli a1, a1, 58 1330; RV64I-NEXT: slli a2, a2, 3 1331; RV64I-NEXT: slli a1, a1, 6 1332; RV64I-NEXT: add a0, a0, a2 1333; RV64I-NEXT: add a0, a0, a1 1334; RV64I-NEXT: ld a0, 0(a0) 1335; RV64I-NEXT: ret 1336; 1337; RV64ZBA-LABEL: array_index_lshr_sh3_sh3: 1338; RV64ZBA: # %bb.0: 1339; RV64ZBA-NEXT: srli a1, a1, 58 1340; RV64ZBA-NEXT: sh3add a1, a1, a2 1341; RV64ZBA-NEXT: sh3add a0, a1, a0 1342; RV64ZBA-NEXT: ld a0, 0(a0) 1343; RV64ZBA-NEXT: ret 1344 %shr = lshr i64 %idx1, 58 1345 %a = getelementptr inbounds [8 x i64], ptr %p, i64 %shr, i64 %idx2 1346 %b = load i64, ptr %a, align 8 1347 ret i64 %b 1348} 1349 1350define i8 @array_index_sh4_sh0(ptr %p, i64 %idx1, i64 %idx2) { 1351; CHECK-LABEL: array_index_sh4_sh0: 1352; CHECK: # %bb.0: 1353; CHECK-NEXT: slli a1, a1, 4 1354; CHECK-NEXT: add a0, a0, a2 1355; CHECK-NEXT: add a0, a0, a1 1356; CHECK-NEXT: lbu a0, 0(a0) 1357; CHECK-NEXT: ret 1358 %a = getelementptr inbounds [16 x i8], ptr %p, i64 %idx1, i64 %idx2 1359 %b = load i8, ptr %a, align 1 1360 ret i8 %b 1361} 1362 1363define i16 @array_index_sh4_sh1(ptr %p, i64 %idx1, i64 %idx2) { 1364; RV64I-LABEL: array_index_sh4_sh1: 1365; RV64I: # %bb.0: 1366; RV64I-NEXT: slli a1, a1, 5 1367; RV64I-NEXT: add a0, a0, a1 1368; RV64I-NEXT: slli a2, a2, 1 1369; RV64I-NEXT: add a0, a0, a2 1370; RV64I-NEXT: lh a0, 0(a0) 1371; RV64I-NEXT: ret 1372; 1373; RV64ZBA-LABEL: array_index_sh4_sh1: 1374; RV64ZBA: # %bb.0: 1375; RV64ZBA-NEXT: slli a1, a1, 5 1376; RV64ZBA-NEXT: add a0, a0, a1 1377; RV64ZBA-NEXT: sh1add a0, a2, a0 1378; RV64ZBA-NEXT: lh a0, 0(a0) 1379; RV64ZBA-NEXT: ret 1380 %a = getelementptr inbounds [16 x i16], ptr %p, i64 %idx1, i64 %idx2 1381 %b = load i16, ptr %a, align 2 1382 ret i16 %b 1383} 1384 1385define i32 @array_index_sh4_sh2(ptr %p, i64 %idx1, i64 %idx2) { 1386; RV64I-LABEL: array_index_sh4_sh2: 1387; RV64I: # %bb.0: 1388; RV64I-NEXT: slli a1, a1, 6 1389; RV64I-NEXT: add a0, a0, a1 1390; RV64I-NEXT: slli a2, a2, 2 1391; RV64I-NEXT: add a0, a0, a2 1392; RV64I-NEXT: lw a0, 0(a0) 1393; RV64I-NEXT: ret 1394; 1395; RV64ZBA-LABEL: array_index_sh4_sh2: 1396; RV64ZBA: # %bb.0: 1397; RV64ZBA-NEXT: slli a1, a1, 6 1398; RV64ZBA-NEXT: add a0, a0, a1 1399; RV64ZBA-NEXT: sh2add a0, a2, a0 1400; RV64ZBA-NEXT: lw a0, 0(a0) 1401; RV64ZBA-NEXT: ret 1402 %a = getelementptr inbounds [16 x i32], ptr %p, i64 %idx1, i64 %idx2 1403 %b = load i32, ptr %a, align 4 1404 ret i32 %b 1405} 1406 1407define i64 @array_index_sh4_sh3(ptr %p, i64 %idx1, i64 %idx2) { 1408; RV64I-LABEL: array_index_sh4_sh3: 1409; RV64I: # %bb.0: 1410; RV64I-NEXT: slli a1, a1, 7 1411; RV64I-NEXT: add a0, a0, a1 1412; RV64I-NEXT: slli a2, a2, 3 1413; RV64I-NEXT: add a0, a0, a2 1414; RV64I-NEXT: ld a0, 0(a0) 1415; RV64I-NEXT: ret 1416; 1417; RV64ZBA-LABEL: array_index_sh4_sh3: 1418; RV64ZBA: # %bb.0: 1419; RV64ZBA-NEXT: slli a1, a1, 7 1420; RV64ZBA-NEXT: add a0, a0, a1 1421; RV64ZBA-NEXT: sh3add a0, a2, a0 1422; RV64ZBA-NEXT: ld a0, 0(a0) 1423; RV64ZBA-NEXT: ret 1424 %a = getelementptr inbounds [16 x i64], ptr %p, i64 %idx1, i64 %idx2 1425 %b = load i64, ptr %a, align 8 1426 ret i64 %b 1427} 1428 1429define ptr @gep_lshr_i32(ptr %0, i64 %1) { 1430; RV64I-LABEL: gep_lshr_i32: 1431; RV64I: # %bb.0: # %entry 1432; RV64I-NEXT: srli a1, a1, 2 1433; RV64I-NEXT: slli a1, a1, 32 1434; RV64I-NEXT: srli a1, a1, 32 1435; RV64I-NEXT: li a2, 80 1436; RV64I-NEXT: mul a1, a1, a2 1437; RV64I-NEXT: add a0, a0, a1 1438; RV64I-NEXT: ret 1439; 1440; RV64ZBA-LABEL: gep_lshr_i32: 1441; RV64ZBA: # %bb.0: # %entry 1442; RV64ZBA-NEXT: srli a1, a1, 2 1443; RV64ZBA-NEXT: zext.w a1, a1 1444; RV64ZBA-NEXT: li a2, 80 1445; RV64ZBA-NEXT: mul a1, a1, a2 1446; RV64ZBA-NEXT: add a0, a0, a1 1447; RV64ZBA-NEXT: ret 1448entry: 1449 %2 = lshr exact i64 %1, 2 1450 %3 = and i64 %2, 4294967295 1451 %5 = getelementptr [80 x i8], ptr %0, i64 %3 1452 ret ptr %5 1453} 1454 1455define i64 @srli_slliuw(i64 %1) { 1456; RV64I-LABEL: srli_slliuw: 1457; RV64I: # %bb.0: # %entry 1458; RV64I-NEXT: srli a0, a0, 2 1459; RV64I-NEXT: slli a0, a0, 32 1460; RV64I-NEXT: srli a0, a0, 28 1461; RV64I-NEXT: ret 1462; 1463; RV64ZBA-LABEL: srli_slliuw: 1464; RV64ZBA: # %bb.0: # %entry 1465; RV64ZBA-NEXT: srli a0, a0, 2 1466; RV64ZBA-NEXT: slli.uw a0, a0, 4 1467; RV64ZBA-NEXT: ret 1468entry: 1469 %2 = lshr exact i64 %1, 2 1470 %3 = and i64 %2, 4294967295 1471 %4 = shl i64 %3, 4 1472 ret i64 %4 1473} 1474 1475define i64 @srli_slliuw_canonical(i64 %0) { 1476; RV64I-LABEL: srli_slliuw_canonical: 1477; RV64I: # %bb.0: # %entry 1478; RV64I-NEXT: li a1, 1 1479; RV64I-NEXT: slli a1, a1, 36 1480; RV64I-NEXT: addi a1, a1, -16 1481; RV64I-NEXT: slli a0, a0, 2 1482; RV64I-NEXT: and a0, a0, a1 1483; RV64I-NEXT: ret 1484; 1485; RV64ZBA-LABEL: srli_slliuw_canonical: 1486; RV64ZBA: # %bb.0: # %entry 1487; RV64ZBA-NEXT: slli a0, a0, 2 1488; RV64ZBA-NEXT: srli a0, a0, 4 1489; RV64ZBA-NEXT: slli.uw a0, a0, 4 1490; RV64ZBA-NEXT: ret 1491entry: 1492 %1 = shl i64 %0, 2 1493 %2 = and i64 %1, 68719476720 1494 ret i64 %2 1495} 1496 1497; Make sure we don't accidentally use slli.uw with a shift of 32. 1498define i64 @srli_slliuw_negative_test(i64 %0) { 1499; CHECK-LABEL: srli_slliuw_negative_test: 1500; CHECK: # %bb.0: # %entry 1501; CHECK-NEXT: srli a0, a0, 6 1502; CHECK-NEXT: slli a0, a0, 32 1503; CHECK-NEXT: ret 1504entry: 1505 %1 = lshr i64 %0, 6 1506 %2 = shl i64 %1, 32 1507 ret i64 %2 1508} 1509 1510define i64 @srli_slli_i16(i64 %1) { 1511; RV64I-LABEL: srli_slli_i16: 1512; RV64I: # %bb.0: # %entry 1513; RV64I-NEXT: srli a0, a0, 2 1514; RV64I-NEXT: slli a0, a0, 48 1515; RV64I-NEXT: srli a0, a0, 48 1516; RV64I-NEXT: slli a0, a0, 4 1517; RV64I-NEXT: ret 1518; 1519; RV64ZBANOZBB-LABEL: srli_slli_i16: 1520; RV64ZBANOZBB: # %bb.0: # %entry 1521; RV64ZBANOZBB-NEXT: srli a0, a0, 2 1522; RV64ZBANOZBB-NEXT: slli a0, a0, 48 1523; RV64ZBANOZBB-NEXT: srli a0, a0, 48 1524; RV64ZBANOZBB-NEXT: slli a0, a0, 4 1525; RV64ZBANOZBB-NEXT: ret 1526; 1527; RV64ZBAZBB-LABEL: srli_slli_i16: 1528; RV64ZBAZBB: # %bb.0: # %entry 1529; RV64ZBAZBB-NEXT: srli a0, a0, 2 1530; RV64ZBAZBB-NEXT: zext.h a0, a0 1531; RV64ZBAZBB-NEXT: slli a0, a0, 4 1532; RV64ZBAZBB-NEXT: ret 1533entry: 1534 %2 = lshr exact i64 %1, 2 1535 %3 = and i64 %2, 65535 1536 %4 = shl i64 %3, 4 1537 ret i64 %4 1538} 1539 1540define i64 @srli_slliuw_2(i64 %1) { 1541; RV64I-LABEL: srli_slliuw_2: 1542; RV64I: # %bb.0: # %entry 1543; RV64I-NEXT: srli a0, a0, 18 1544; RV64I-NEXT: slli a0, a0, 32 1545; RV64I-NEXT: srli a0, a0, 29 1546; RV64I-NEXT: ret 1547; 1548; RV64ZBA-LABEL: srli_slliuw_2: 1549; RV64ZBA: # %bb.0: # %entry 1550; RV64ZBA-NEXT: srli a0, a0, 18 1551; RV64ZBA-NEXT: slli.uw a0, a0, 3 1552; RV64ZBA-NEXT: ret 1553entry: 1554 %2 = lshr i64 %1, 18 1555 %3 = and i64 %2, 4294967295 1556 %4 = shl i64 %3, 3 1557 ret i64 %4 1558} 1559 1560define i64 @srli_slliuw_canonical_2(i64 %0) { 1561; RV64I-LABEL: srli_slliuw_canonical_2: 1562; RV64I: # %bb.0: # %entry 1563; RV64I-NEXT: li a1, 1 1564; RV64I-NEXT: slli a1, a1, 35 1565; RV64I-NEXT: addi a1, a1, -8 1566; RV64I-NEXT: srli a0, a0, 15 1567; RV64I-NEXT: and a0, a0, a1 1568; RV64I-NEXT: ret 1569; 1570; RV64ZBA-LABEL: srli_slliuw_canonical_2: 1571; RV64ZBA: # %bb.0: # %entry 1572; RV64ZBA-NEXT: srli a0, a0, 15 1573; RV64ZBA-NEXT: srli a0, a0, 3 1574; RV64ZBA-NEXT: slli.uw a0, a0, 3 1575; RV64ZBA-NEXT: ret 1576entry: 1577 %1 = lshr i64 %0, 15 1578 %2 = and i64 %1, 34359738360 1579 ret i64 %2 1580} 1581 1582define ptr @srai_srli_sh3add(ptr %0, i64 %1) nounwind { 1583; RV64I-LABEL: srai_srli_sh3add: 1584; RV64I: # %bb.0: # %entry 1585; RV64I-NEXT: srai a1, a1, 32 1586; RV64I-NEXT: srli a1, a1, 6 1587; RV64I-NEXT: slli a1, a1, 3 1588; RV64I-NEXT: add a0, a0, a1 1589; RV64I-NEXT: ret 1590; 1591; RV64ZBA-LABEL: srai_srli_sh3add: 1592; RV64ZBA: # %bb.0: # %entry 1593; RV64ZBA-NEXT: srai a1, a1, 32 1594; RV64ZBA-NEXT: srli a1, a1, 6 1595; RV64ZBA-NEXT: sh3add a0, a1, a0 1596; RV64ZBA-NEXT: ret 1597entry: 1598 %2 = ashr i64 %1, 32 1599 %3 = lshr i64 %2, 6 1600 %4 = getelementptr i64, ptr %0, i64 %3 1601 ret ptr %4 1602} 1603 1604define ptr @srai_srli_slli(ptr %0, i64 %1) nounwind { 1605; CHECK-LABEL: srai_srli_slli: 1606; CHECK: # %bb.0: # %entry 1607; CHECK-NEXT: srai a1, a1, 32 1608; CHECK-NEXT: srli a1, a1, 6 1609; CHECK-NEXT: slli a1, a1, 4 1610; CHECK-NEXT: add a0, a0, a1 1611; CHECK-NEXT: ret 1612entry: 1613 %2 = ashr i64 %1, 32 1614 %3 = lshr i64 %2, 6 1615 %4 = getelementptr i128, ptr %0, i64 %3 1616 ret ptr %4 1617} 1618 1619; Negative to make sure the peephole added for srai_srli_slli and 1620; srai_srli_sh3add doesn't break this. 1621define i64 @srai_andi(i64 %x) nounwind { 1622; CHECK-LABEL: srai_andi: 1623; CHECK: # %bb.0: # %entry 1624; CHECK-NEXT: srai a0, a0, 8 1625; CHECK-NEXT: andi a0, a0, -8 1626; CHECK-NEXT: ret 1627entry: 1628 %y = ashr i64 %x, 8 1629 %z = and i64 %y, -8 1630 ret i64 %z 1631} 1632 1633; Negative to make sure the peephole added for srai_srli_slli and 1634; srai_srli_sh3add doesn't break this. 1635define i64 @srai_lui_and(i64 %x) nounwind { 1636; CHECK-LABEL: srai_lui_and: 1637; CHECK: # %bb.0: # %entry 1638; CHECK-NEXT: lui a1, 1048574 1639; CHECK-NEXT: srai a0, a0, 8 1640; CHECK-NEXT: and a0, a0, a1 1641; CHECK-NEXT: ret 1642entry: 1643 %y = ashr i64 %x, 8 1644 %z = and i64 %y, -8192 1645 ret i64 %z 1646} 1647 1648define i64 @add_u32simm32_zextw(i64 %x) nounwind { 1649; RV64I-LABEL: add_u32simm32_zextw: 1650; RV64I: # %bb.0: # %entry 1651; RV64I-NEXT: li a1, 1 1652; RV64I-NEXT: slli a1, a1, 32 1653; RV64I-NEXT: addi a1, a1, -2 1654; RV64I-NEXT: add a0, a0, a1 1655; RV64I-NEXT: addi a1, a1, 1 1656; RV64I-NEXT: and a0, a0, a1 1657; RV64I-NEXT: ret 1658; 1659; RV64ZBA-LABEL: add_u32simm32_zextw: 1660; RV64ZBA: # %bb.0: # %entry 1661; RV64ZBA-NEXT: li a1, -2 1662; RV64ZBA-NEXT: zext.w a1, a1 1663; RV64ZBA-NEXT: add a0, a0, a1 1664; RV64ZBA-NEXT: zext.w a0, a0 1665; RV64ZBA-NEXT: ret 1666entry: 1667 %add = add i64 %x, 4294967294 1668 %and = and i64 %add, 4294967295 1669 ret i64 %and 1670} 1671