1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV64I 4; RUN: llc -mtriple=riscv64 -mattr=+zbkb -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64ZBKB 6 7define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind { 8; RV64I-LABEL: pack_i32: 9; RV64I: # %bb.0: 10; RV64I-NEXT: slli a0, a0, 48 11; RV64I-NEXT: srli a0, a0, 48 12; RV64I-NEXT: slliw a1, a1, 16 13; RV64I-NEXT: or a0, a1, a0 14; RV64I-NEXT: ret 15; 16; RV64ZBKB-LABEL: pack_i32: 17; RV64ZBKB: # %bb.0: 18; RV64ZBKB-NEXT: packw a0, a0, a1 19; RV64ZBKB-NEXT: ret 20 %shl = and i32 %a, 65535 21 %shl1 = shl i32 %b, 16 22 %or = or i32 %shl1, %shl 23 ret i32 %or 24} 25 26define signext i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind { 27; RV64I-LABEL: pack_i32_2: 28; RV64I: # %bb.0: 29; RV64I-NEXT: slliw a1, a1, 16 30; RV64I-NEXT: or a0, a1, a0 31; RV64I-NEXT: ret 32; 33; RV64ZBKB-LABEL: pack_i32_2: 34; RV64ZBKB: # %bb.0: 35; RV64ZBKB-NEXT: packw a0, a0, a1 36; RV64ZBKB-NEXT: ret 37 %zexta = zext i16 %a to i32 38 %zextb = zext i16 %b to i32 39 %shl1 = shl i32 %zextb, 16 40 %or = or i32 %shl1, %zexta 41 ret i32 %or 42} 43 44; Test case where we don't have a sign_extend_inreg after the or. 45define signext i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 signext %2) { 46; RV64I-LABEL: pack_i32_3: 47; RV64I: # %bb.0: 48; RV64I-NEXT: slli a0, a0, 16 49; RV64I-NEXT: or a0, a0, a1 50; RV64I-NEXT: addw a0, a0, a2 51; RV64I-NEXT: ret 52; 53; RV64ZBKB-LABEL: pack_i32_3: 54; RV64ZBKB: # %bb.0: 55; RV64ZBKB-NEXT: packw a0, a1, a0 56; RV64ZBKB-NEXT: addw a0, a0, a2 57; RV64ZBKB-NEXT: ret 58 %4 = zext i16 %0 to i32 59 %5 = shl nuw i32 %4, 16 60 %6 = zext i16 %1 to i32 61 %7 = or i32 %5, %6 62 %8 = add i32 %7, %2 63 ret i32 %8 64} 65 66define i64 @pack_i64(i64 %a, i64 %b) nounwind { 67; RV64I-LABEL: pack_i64: 68; RV64I: # %bb.0: 69; RV64I-NEXT: slli a0, a0, 32 70; RV64I-NEXT: srli a0, a0, 32 71; RV64I-NEXT: slli a1, a1, 32 72; RV64I-NEXT: or a0, a1, a0 73; RV64I-NEXT: ret 74; 75; RV64ZBKB-LABEL: pack_i64: 76; RV64ZBKB: # %bb.0: 77; RV64ZBKB-NEXT: pack a0, a0, a1 78; RV64ZBKB-NEXT: ret 79 %shl = and i64 %a, 4294967295 80 %shl1 = shl i64 %b, 32 81 %or = or i64 %shl1, %shl 82 ret i64 %or 83} 84 85define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind { 86; RV64I-LABEL: pack_i64_2: 87; RV64I: # %bb.0: 88; RV64I-NEXT: slli a0, a0, 32 89; RV64I-NEXT: srli a0, a0, 32 90; RV64I-NEXT: slli a1, a1, 32 91; RV64I-NEXT: or a0, a1, a0 92; RV64I-NEXT: ret 93; 94; RV64ZBKB-LABEL: pack_i64_2: 95; RV64ZBKB: # %bb.0: 96; RV64ZBKB-NEXT: pack a0, a0, a1 97; RV64ZBKB-NEXT: ret 98 %zexta = zext i32 %a to i64 99 %zextb = zext i32 %b to i64 100 %shl1 = shl i64 %zextb, 32 101 %or = or i64 %shl1, %zexta 102 ret i64 %or 103} 104 105define i64 @pack_i64_3(ptr %0, ptr %1) { 106; RV64I-LABEL: pack_i64_3: 107; RV64I: # %bb.0: 108; RV64I-NEXT: lw a0, 0(a0) 109; RV64I-NEXT: lwu a1, 0(a1) 110; RV64I-NEXT: slli a0, a0, 32 111; RV64I-NEXT: or a0, a0, a1 112; RV64I-NEXT: ret 113; 114; RV64ZBKB-LABEL: pack_i64_3: 115; RV64ZBKB: # %bb.0: 116; RV64ZBKB-NEXT: lw a0, 0(a0) 117; RV64ZBKB-NEXT: lwu a1, 0(a1) 118; RV64ZBKB-NEXT: pack a0, a1, a0 119; RV64ZBKB-NEXT: ret 120 %3 = load i32, ptr %0, align 4 121 %4 = zext i32 %3 to i64 122 %5 = shl i64 %4, 32 123 %6 = load i32, ptr %1, align 4 124 %7 = zext i32 %6 to i64 125 %8 = or i64 %5, %7 126 ret i64 %8 127} 128 129define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind { 130; RV64I-LABEL: packh_i32: 131; RV64I: # %bb.0: 132; RV64I-NEXT: andi a0, a0, 255 133; RV64I-NEXT: slli a1, a1, 56 134; RV64I-NEXT: srli a1, a1, 48 135; RV64I-NEXT: or a0, a1, a0 136; RV64I-NEXT: ret 137; 138; RV64ZBKB-LABEL: packh_i32: 139; RV64ZBKB: # %bb.0: 140; RV64ZBKB-NEXT: packh a0, a0, a1 141; RV64ZBKB-NEXT: ret 142 %and = and i32 %a, 255 143 %and1 = shl i32 %b, 8 144 %shl = and i32 %and1, 65280 145 %or = or i32 %shl, %and 146 ret i32 %or 147} 148 149define i32 @packh_i32_2(i32 %a, i32 %b) nounwind { 150; RV64I-LABEL: packh_i32_2: 151; RV64I: # %bb.0: 152; RV64I-NEXT: andi a0, a0, 255 153; RV64I-NEXT: andi a1, a1, 255 154; RV64I-NEXT: slli a1, a1, 8 155; RV64I-NEXT: or a0, a1, a0 156; RV64I-NEXT: ret 157; 158; RV64ZBKB-LABEL: packh_i32_2: 159; RV64ZBKB: # %bb.0: 160; RV64ZBKB-NEXT: packh a0, a0, a1 161; RV64ZBKB-NEXT: ret 162 %and = and i32 %a, 255 163 %and1 = and i32 %b, 255 164 %shl = shl i32 %and1, 8 165 %or = or i32 %shl, %and 166 ret i32 %or 167} 168 169define i64 @packh_i64(i64 %a, i64 %b) nounwind { 170; RV64I-LABEL: packh_i64: 171; RV64I: # %bb.0: 172; RV64I-NEXT: andi a0, a0, 255 173; RV64I-NEXT: slli a1, a1, 56 174; RV64I-NEXT: srli a1, a1, 48 175; RV64I-NEXT: or a0, a1, a0 176; RV64I-NEXT: ret 177; 178; RV64ZBKB-LABEL: packh_i64: 179; RV64ZBKB: # %bb.0: 180; RV64ZBKB-NEXT: packh a0, a0, a1 181; RV64ZBKB-NEXT: ret 182 %and = and i64 %a, 255 183 %and1 = shl i64 %b, 8 184 %shl = and i64 %and1, 65280 185 %or = or i64 %shl, %and 186 ret i64 %or 187} 188 189define i64 @packh_i64_2(i64 %a, i64 %b) nounwind { 190; RV64I-LABEL: packh_i64_2: 191; RV64I: # %bb.0: 192; RV64I-NEXT: andi a0, a0, 255 193; RV64I-NEXT: andi a1, a1, 255 194; RV64I-NEXT: slli a1, a1, 8 195; RV64I-NEXT: or a0, a1, a0 196; RV64I-NEXT: ret 197; 198; RV64ZBKB-LABEL: packh_i64_2: 199; RV64ZBKB: # %bb.0: 200; RV64ZBKB-NEXT: packh a0, a0, a1 201; RV64ZBKB-NEXT: ret 202 %and = and i64 %a, 255 203 %and1 = and i64 %b, 255 204 %shl = shl i64 %and1, 8 205 %or = or i64 %shl, %and 206 ret i64 %or 207} 208 209define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind { 210; RV64I-LABEL: packh_i16: 211; RV64I: # %bb.0: 212; RV64I-NEXT: slli a1, a1, 8 213; RV64I-NEXT: or a0, a1, a0 214; RV64I-NEXT: ret 215; 216; RV64ZBKB-LABEL: packh_i16: 217; RV64ZBKB: # %bb.0: 218; RV64ZBKB-NEXT: packh a0, a0, a1 219; RV64ZBKB-NEXT: ret 220 %zext = zext i8 %a to i16 221 %zext1 = zext i8 %b to i16 222 %shl = shl i16 %zext1, 8 223 %or = or i16 %shl, %zext 224 ret i16 %or 225} 226 227define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) { 228; RV64I-LABEL: packh_i16_2: 229; RV64I: # %bb.0: 230; RV64I-NEXT: add a0, a1, a0 231; RV64I-NEXT: slli a0, a0, 8 232; RV64I-NEXT: or a0, a0, a2 233; RV64I-NEXT: slli a0, a0, 48 234; RV64I-NEXT: srli a0, a0, 48 235; RV64I-NEXT: ret 236; 237; RV64ZBKB-LABEL: packh_i16_2: 238; RV64ZBKB: # %bb.0: 239; RV64ZBKB-NEXT: add a0, a1, a0 240; RV64ZBKB-NEXT: packh a0, a2, a0 241; RV64ZBKB-NEXT: ret 242 %4 = add i8 %1, %0 243 %5 = zext i8 %4 to i16 244 %6 = shl i16 %5, 8 245 %7 = zext i8 %2 to i16 246 %8 = or i16 %6, %7 247 ret i16 %8 248} 249 250define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) { 251; RV64I-LABEL: packh_i16_3: 252; RV64I: # %bb.0: 253; RV64I-NEXT: add a0, a1, a0 254; RV64I-NEXT: slli a0, a0, 8 255; RV64I-NEXT: or a0, a0, a2 256; RV64I-NEXT: sh a0, 0(a3) 257; RV64I-NEXT: ret 258; 259; RV64ZBKB-LABEL: packh_i16_3: 260; RV64ZBKB: # %bb.0: 261; RV64ZBKB-NEXT: add a0, a1, a0 262; RV64ZBKB-NEXT: packh a0, a2, a0 263; RV64ZBKB-NEXT: sh a0, 0(a3) 264; RV64ZBKB-NEXT: ret 265 %4 = add i8 %1, %0 266 %5 = zext i8 %4 to i16 267 %6 = shl i16 %5, 8 268 %7 = zext i8 %2 to i16 269 %8 = or i16 %6, %7 270 store i16 %8, ptr %p 271 ret void 272} 273 274define i64 @pack_i64_allWUsers(i32 signext %0, i32 signext %1, i32 signext %2) { 275; RV64I-LABEL: pack_i64_allWUsers: 276; RV64I: # %bb.0: 277; RV64I-NEXT: add a0, a1, a0 278; RV64I-NEXT: slli a2, a2, 32 279; RV64I-NEXT: slli a0, a0, 32 280; RV64I-NEXT: srli a2, a2, 32 281; RV64I-NEXT: or a0, a0, a2 282; RV64I-NEXT: ret 283; 284; RV64ZBKB-LABEL: pack_i64_allWUsers: 285; RV64ZBKB: # %bb.0: 286; RV64ZBKB-NEXT: add a0, a1, a0 287; RV64ZBKB-NEXT: pack a0, a2, a0 288; RV64ZBKB-NEXT: ret 289 %4 = add i32 %1, %0 290 %5 = zext i32 %4 to i64 291 %6 = shl i64 %5, 32 292 %7 = zext i32 %2 to i64 293 %8 = or i64 %6, %7 294 ret i64 %8 295} 296 297define signext i32 @pack_i32_allWUsers(i16 zeroext %0, i16 zeroext %1, i16 zeroext %2) { 298; RV64I-LABEL: pack_i32_allWUsers: 299; RV64I: # %bb.0: 300; RV64I-NEXT: add a0, a1, a0 301; RV64I-NEXT: slliw a0, a0, 16 302; RV64I-NEXT: or a0, a0, a2 303; RV64I-NEXT: ret 304; 305; RV64ZBKB-LABEL: pack_i32_allWUsers: 306; RV64ZBKB: # %bb.0: 307; RV64ZBKB-NEXT: add a0, a1, a0 308; RV64ZBKB-NEXT: packw a0, a2, a0 309; RV64ZBKB-NEXT: ret 310 %4 = add i16 %1, %0 311 %5 = zext i16 %4 to i32 312 %6 = shl i32 %5, 16 313 %7 = zext i16 %2 to i32 314 %8 = or i32 %6, %7 315 ret i32 %8 316} 317 318define i64 @pack_i64_imm() { 319; RV64I-LABEL: pack_i64_imm: 320; RV64I: # %bb.0: 321; RV64I-NEXT: lui a0, 65793 322; RV64I-NEXT: addiw a0, a0, 16 323; RV64I-NEXT: slli a1, a0, 32 324; RV64I-NEXT: add a0, a0, a1 325; RV64I-NEXT: ret 326; 327; RV64ZBKB-LABEL: pack_i64_imm: 328; RV64ZBKB: # %bb.0: 329; RV64ZBKB-NEXT: lui a0, 65793 330; RV64ZBKB-NEXT: addi a0, a0, 16 331; RV64ZBKB-NEXT: pack a0, a0, a0 332; RV64ZBKB-NEXT: ret 333 ret i64 1157442765409226768 ; 0x0101010101010101 334} 335 336define i32 @zexth_i32(i32 %a) nounwind { 337; RV64I-LABEL: zexth_i32: 338; RV64I: # %bb.0: 339; RV64I-NEXT: slli a0, a0, 48 340; RV64I-NEXT: srli a0, a0, 48 341; RV64I-NEXT: ret 342; 343; RV64ZBKB-LABEL: zexth_i32: 344; RV64ZBKB: # %bb.0: 345; RV64ZBKB-NEXT: zext.h a0, a0 346; RV64ZBKB-NEXT: ret 347 %and = and i32 %a, 65535 348 ret i32 %and 349} 350 351define i64 @zexth_i64(i64 %a) nounwind { 352; RV64I-LABEL: zexth_i64: 353; RV64I: # %bb.0: 354; RV64I-NEXT: slli a0, a0, 48 355; RV64I-NEXT: srli a0, a0, 48 356; RV64I-NEXT: ret 357; 358; RV64ZBKB-LABEL: zexth_i64: 359; RV64ZBKB: # %bb.0: 360; RV64ZBKB-NEXT: zext.h a0, a0 361; RV64ZBKB-NEXT: ret 362 %and = and i64 %a, 65535 363 ret i64 %and 364} 365 366define i32 @zext_i16_to_i32(i16 %a) nounwind { 367; RV64I-LABEL: zext_i16_to_i32: 368; RV64I: # %bb.0: 369; RV64I-NEXT: slli a0, a0, 48 370; RV64I-NEXT: srli a0, a0, 48 371; RV64I-NEXT: ret 372; 373; RV64ZBKB-LABEL: zext_i16_to_i32: 374; RV64ZBKB: # %bb.0: 375; RV64ZBKB-NEXT: zext.h a0, a0 376; RV64ZBKB-NEXT: ret 377 %1 = zext i16 %a to i32 378 ret i32 %1 379} 380 381define i64 @zext_i16_to_i64(i16 %a) nounwind { 382; RV64I-LABEL: zext_i16_to_i64: 383; RV64I: # %bb.0: 384; RV64I-NEXT: slli a0, a0, 48 385; RV64I-NEXT: srli a0, a0, 48 386; RV64I-NEXT: ret 387; 388; RV64ZBKB-LABEL: zext_i16_to_i64: 389; RV64ZBKB: # %bb.0: 390; RV64ZBKB-NEXT: zext.h a0, a0 391; RV64ZBKB-NEXT: ret 392 %1 = zext i16 %a to i64 393 ret i64 %1 394} 395