1182aa0cbSCraig Topper; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2182aa0cbSCraig Topper; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3182aa0cbSCraig Topper; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I 4182aa0cbSCraig Topper; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \ 5182aa0cbSCraig Topper; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBKB 6182aa0cbSCraig Topper 7182aa0cbSCraig Topperdefine i32 @pack_i32(i32 %a, i32 %b) nounwind { 8182aa0cbSCraig Topper; RV32I-LABEL: pack_i32: 9182aa0cbSCraig Topper; RV32I: # %bb.0: 10182aa0cbSCraig Topper; RV32I-NEXT: slli a0, a0, 16 11182aa0cbSCraig Topper; RV32I-NEXT: srli a0, a0, 16 12182aa0cbSCraig Topper; RV32I-NEXT: slli a1, a1, 16 13182aa0cbSCraig Topper; RV32I-NEXT: or a0, a1, a0 14182aa0cbSCraig Topper; RV32I-NEXT: ret 15182aa0cbSCraig Topper; 16182aa0cbSCraig Topper; RV32ZBKB-LABEL: pack_i32: 17182aa0cbSCraig Topper; RV32ZBKB: # %bb.0: 18182aa0cbSCraig Topper; RV32ZBKB-NEXT: pack a0, a0, a1 19182aa0cbSCraig Topper; RV32ZBKB-NEXT: ret 20182aa0cbSCraig Topper %shl = and i32 %a, 65535 21182aa0cbSCraig Topper %shl1 = shl i32 %b, 16 22182aa0cbSCraig Topper %or = or i32 %shl1, %shl 23182aa0cbSCraig Topper ret i32 %or 24182aa0cbSCraig Topper} 25182aa0cbSCraig Topper 2695388f73SCraig Topperdefine i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind { 2795388f73SCraig Topper; RV32I-LABEL: pack_i32_2: 2895388f73SCraig Topper; RV32I: # %bb.0: 2995388f73SCraig Topper; RV32I-NEXT: slli a1, a1, 16 3095388f73SCraig Topper; RV32I-NEXT: or a0, a1, a0 3195388f73SCraig Topper; RV32I-NEXT: ret 3295388f73SCraig Topper; 3395388f73SCraig Topper; RV32ZBKB-LABEL: pack_i32_2: 3495388f73SCraig Topper; RV32ZBKB: # %bb.0: 3595388f73SCraig Topper; RV32ZBKB-NEXT: pack a0, a0, a1 3695388f73SCraig Topper; RV32ZBKB-NEXT: ret 3795388f73SCraig Topper %zexta = zext i16 %a to i32 3895388f73SCraig Topper %zextb = zext i16 %b to i32 3995388f73SCraig Topper %shl1 = shl i32 %zextb, 16 4095388f73SCraig Topper %or = or i32 %shl1, %zexta 4195388f73SCraig Topper ret i32 %or 4295388f73SCraig Topper} 4395388f73SCraig Topper 441a8ba9e1SCraig Topperdefine i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) { 451a8ba9e1SCraig Topper; RV32I-LABEL: pack_i32_3: 461a8ba9e1SCraig Topper; RV32I: # %bb.0: 471a8ba9e1SCraig Topper; RV32I-NEXT: slli a0, a0, 16 481a8ba9e1SCraig Topper; RV32I-NEXT: or a0, a0, a1 491a8ba9e1SCraig Topper; RV32I-NEXT: add a0, a0, a2 501a8ba9e1SCraig Topper; RV32I-NEXT: ret 511a8ba9e1SCraig Topper; 521a8ba9e1SCraig Topper; RV32ZBKB-LABEL: pack_i32_3: 531a8ba9e1SCraig Topper; RV32ZBKB: # %bb.0: 541a8ba9e1SCraig Topper; RV32ZBKB-NEXT: pack a0, a1, a0 551a8ba9e1SCraig Topper; RV32ZBKB-NEXT: add a0, a0, a2 561a8ba9e1SCraig Topper; RV32ZBKB-NEXT: ret 571a8ba9e1SCraig Topper %4 = zext i16 %0 to i32 581a8ba9e1SCraig Topper %5 = shl nuw i32 %4, 16 591a8ba9e1SCraig Topper %6 = zext i16 %1 to i32 601a8ba9e1SCraig Topper %7 = or i32 %5, %6 611a8ba9e1SCraig Topper %8 = add i32 %7, %2 621a8ba9e1SCraig Topper ret i32 %8 631a8ba9e1SCraig Topper} 641a8ba9e1SCraig Topper 65182aa0cbSCraig Topper; As we are not matching directly i64 code patterns on RV32 some i64 patterns 66182aa0cbSCraig Topper; don't have yet any matching bit manipulation instructions on RV32. 67182aa0cbSCraig Topper; This test is presented here in case future expansions of the Bitmanip 68182aa0cbSCraig Topper; extensions introduce instructions suitable for this pattern. 69182aa0cbSCraig Topper 70182aa0cbSCraig Topperdefine i64 @pack_i64(i64 %a, i64 %b) nounwind { 71182aa0cbSCraig Topper; CHECK-LABEL: pack_i64: 72182aa0cbSCraig Topper; CHECK: # %bb.0: 73182aa0cbSCraig Topper; CHECK-NEXT: mv a1, a2 74182aa0cbSCraig Topper; CHECK-NEXT: ret 75182aa0cbSCraig Topper %shl = and i64 %a, 4294967295 76182aa0cbSCraig Topper %shl1 = shl i64 %b, 32 77182aa0cbSCraig Topper %or = or i64 %shl1, %shl 78182aa0cbSCraig Topper ret i64 %or 79182aa0cbSCraig Topper} 80182aa0cbSCraig Topper 8195388f73SCraig Topperdefine i64 @pack_i64_2(i32 %a, i32 %b) nounwind { 8295388f73SCraig Topper; CHECK-LABEL: pack_i64_2: 8395388f73SCraig Topper; CHECK: # %bb.0: 8495388f73SCraig Topper; CHECK-NEXT: ret 8595388f73SCraig Topper %zexta = zext i32 %a to i64 8695388f73SCraig Topper %zextb = zext i32 %b to i64 8795388f73SCraig Topper %shl1 = shl i64 %zextb, 32 8895388f73SCraig Topper %or = or i64 %shl1, %zexta 8995388f73SCraig Topper ret i64 %or 9095388f73SCraig Topper} 9195388f73SCraig Topper 9213e32a8aSCraig Topperdefine i64 @pack_i64_3(ptr %0, ptr %1) { 9313e32a8aSCraig Topper; CHECK-LABEL: pack_i64_3: 9413e32a8aSCraig Topper; CHECK: # %bb.0: 9513e32a8aSCraig Topper; CHECK-NEXT: lw a2, 0(a0) 9613e32a8aSCraig Topper; CHECK-NEXT: lw a0, 0(a1) 9713e32a8aSCraig Topper; CHECK-NEXT: mv a1, a2 9813e32a8aSCraig Topper; CHECK-NEXT: ret 9913e32a8aSCraig Topper %3 = load i32, ptr %0, align 4 10013e32a8aSCraig Topper %4 = zext i32 %3 to i64 10113e32a8aSCraig Topper %5 = shl i64 %4, 32 10213e32a8aSCraig Topper %6 = load i32, ptr %1, align 4 10313e32a8aSCraig Topper %7 = zext i32 %6 to i64 10413e32a8aSCraig Topper %8 = or i64 %5, %7 10513e32a8aSCraig Topper ret i64 %8 10613e32a8aSCraig Topper} 10713e32a8aSCraig Topper 108182aa0cbSCraig Topperdefine i32 @packh_i32(i32 %a, i32 %b) nounwind { 109182aa0cbSCraig Topper; RV32I-LABEL: packh_i32: 110182aa0cbSCraig Topper; RV32I: # %bb.0: 111182aa0cbSCraig Topper; RV32I-NEXT: andi a0, a0, 255 112182aa0cbSCraig Topper; RV32I-NEXT: slli a1, a1, 24 113182aa0cbSCraig Topper; RV32I-NEXT: srli a1, a1, 16 114182aa0cbSCraig Topper; RV32I-NEXT: or a0, a1, a0 115182aa0cbSCraig Topper; RV32I-NEXT: ret 116182aa0cbSCraig Topper; 117182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i32: 118182aa0cbSCraig Topper; RV32ZBKB: # %bb.0: 119182aa0cbSCraig Topper; RV32ZBKB-NEXT: packh a0, a0, a1 120182aa0cbSCraig Topper; RV32ZBKB-NEXT: ret 121182aa0cbSCraig Topper %and = and i32 %a, 255 122182aa0cbSCraig Topper %and1 = shl i32 %b, 8 123182aa0cbSCraig Topper %shl = and i32 %and1, 65280 124182aa0cbSCraig Topper %or = or i32 %shl, %and 125182aa0cbSCraig Topper ret i32 %or 126182aa0cbSCraig Topper} 127182aa0cbSCraig Topper 128182aa0cbSCraig Topperdefine i32 @packh_i32_2(i32 %a, i32 %b) nounwind { 129182aa0cbSCraig Topper; RV32I-LABEL: packh_i32_2: 130182aa0cbSCraig Topper; RV32I: # %bb.0: 131182aa0cbSCraig Topper; RV32I-NEXT: andi a0, a0, 255 132182aa0cbSCraig Topper; RV32I-NEXT: andi a1, a1, 255 133182aa0cbSCraig Topper; RV32I-NEXT: slli a1, a1, 8 134182aa0cbSCraig Topper; RV32I-NEXT: or a0, a1, a0 135182aa0cbSCraig Topper; RV32I-NEXT: ret 136182aa0cbSCraig Topper; 137182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i32_2: 138182aa0cbSCraig Topper; RV32ZBKB: # %bb.0: 139182aa0cbSCraig Topper; RV32ZBKB-NEXT: packh a0, a0, a1 140182aa0cbSCraig Topper; RV32ZBKB-NEXT: ret 141182aa0cbSCraig Topper %and = and i32 %a, 255 142182aa0cbSCraig Topper %and1 = and i32 %b, 255 143182aa0cbSCraig Topper %shl = shl i32 %and1, 8 144182aa0cbSCraig Topper %or = or i32 %shl, %and 145182aa0cbSCraig Topper ret i32 %or 146182aa0cbSCraig Topper} 147182aa0cbSCraig Topper 148182aa0cbSCraig Topperdefine i64 @packh_i64(i64 %a, i64 %b) nounwind { 149182aa0cbSCraig Topper; RV32I-LABEL: packh_i64: 150182aa0cbSCraig Topper; RV32I: # %bb.0: 151182aa0cbSCraig Topper; RV32I-NEXT: andi a0, a0, 255 152a2b5b584SCraig Topper; RV32I-NEXT: slli a2, a2, 24 153a8c79121SCraig Topper; RV32I-NEXT: srli a2, a2, 16 154a8c79121SCraig Topper; RV32I-NEXT: or a0, a2, a0 155182aa0cbSCraig Topper; RV32I-NEXT: li a1, 0 156182aa0cbSCraig Topper; RV32I-NEXT: ret 157182aa0cbSCraig Topper; 158182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i64: 159182aa0cbSCraig Topper; RV32ZBKB: # %bb.0: 160182aa0cbSCraig Topper; RV32ZBKB-NEXT: packh a0, a0, a2 161182aa0cbSCraig Topper; RV32ZBKB-NEXT: li a1, 0 162182aa0cbSCraig Topper; RV32ZBKB-NEXT: ret 163182aa0cbSCraig Topper %and = and i64 %a, 255 164182aa0cbSCraig Topper %and1 = shl i64 %b, 8 165182aa0cbSCraig Topper %shl = and i64 %and1, 65280 166182aa0cbSCraig Topper %or = or i64 %shl, %and 167182aa0cbSCraig Topper ret i64 %or 168182aa0cbSCraig Topper} 169182aa0cbSCraig Topper 170182aa0cbSCraig Topperdefine i64 @packh_i64_2(i64 %a, i64 %b) nounwind { 171182aa0cbSCraig Topper; RV32I-LABEL: packh_i64_2: 172182aa0cbSCraig Topper; RV32I: # %bb.0: 173182aa0cbSCraig Topper; RV32I-NEXT: andi a0, a0, 255 174182aa0cbSCraig Topper; RV32I-NEXT: andi a1, a2, 255 175182aa0cbSCraig Topper; RV32I-NEXT: slli a1, a1, 8 176182aa0cbSCraig Topper; RV32I-NEXT: or a0, a1, a0 177182aa0cbSCraig Topper; RV32I-NEXT: li a1, 0 178182aa0cbSCraig Topper; RV32I-NEXT: ret 179182aa0cbSCraig Topper; 180182aa0cbSCraig Topper; RV32ZBKB-LABEL: packh_i64_2: 181182aa0cbSCraig Topper; RV32ZBKB: # %bb.0: 182182aa0cbSCraig Topper; RV32ZBKB-NEXT: packh a0, a0, a2 183182aa0cbSCraig Topper; RV32ZBKB-NEXT: li a1, 0 184182aa0cbSCraig Topper; RV32ZBKB-NEXT: ret 185182aa0cbSCraig Topper %and = and i64 %a, 255 186182aa0cbSCraig Topper %and1 = and i64 %b, 255 187182aa0cbSCraig Topper %shl = shl i64 %and1, 8 188182aa0cbSCraig Topper %or = or i64 %shl, %and 189182aa0cbSCraig Topper ret i64 %or 190182aa0cbSCraig Topper} 19140ae4b89SCraig Topper 19240ae4b89SCraig Topper 19340ae4b89SCraig Topperdefine zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind { 19440ae4b89SCraig Topper; RV32I-LABEL: packh_i16: 19540ae4b89SCraig Topper; RV32I: # %bb.0: 19640ae4b89SCraig Topper; RV32I-NEXT: slli a1, a1, 8 19740ae4b89SCraig Topper; RV32I-NEXT: or a0, a1, a0 19840ae4b89SCraig Topper; RV32I-NEXT: ret 19940ae4b89SCraig Topper; 20040ae4b89SCraig Topper; RV32ZBKB-LABEL: packh_i16: 20140ae4b89SCraig Topper; RV32ZBKB: # %bb.0: 20240ae4b89SCraig Topper; RV32ZBKB-NEXT: packh a0, a0, a1 20340ae4b89SCraig Topper; RV32ZBKB-NEXT: ret 20440ae4b89SCraig Topper %zext = zext i8 %a to i16 20540ae4b89SCraig Topper %zext1 = zext i8 %b to i16 20640ae4b89SCraig Topper %shl = shl i16 %zext1, 8 20740ae4b89SCraig Topper %or = or i16 %shl, %zext 20840ae4b89SCraig Topper ret i16 %or 20940ae4b89SCraig Topper} 2103ac93d1fSCraig Topper 2113ac93d1fSCraig Topper 2123ac93d1fSCraig Topperdefine zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) { 2133ac93d1fSCraig Topper; RV32I-LABEL: packh_i16_2: 2143ac93d1fSCraig Topper; RV32I: # %bb.0: 2153ac93d1fSCraig Topper; RV32I-NEXT: add a0, a1, a0 2163ac93d1fSCraig Topper; RV32I-NEXT: slli a0, a0, 8 2173ac93d1fSCraig Topper; RV32I-NEXT: or a0, a0, a2 2183ac93d1fSCraig Topper; RV32I-NEXT: slli a0, a0, 16 2193ac93d1fSCraig Topper; RV32I-NEXT: srli a0, a0, 16 2203ac93d1fSCraig Topper; RV32I-NEXT: ret 2213ac93d1fSCraig Topper; 2223ac93d1fSCraig Topper; RV32ZBKB-LABEL: packh_i16_2: 2233ac93d1fSCraig Topper; RV32ZBKB: # %bb.0: 2243ac93d1fSCraig Topper; RV32ZBKB-NEXT: add a0, a1, a0 2253ac93d1fSCraig Topper; RV32ZBKB-NEXT: packh a0, a2, a0 2263ac93d1fSCraig Topper; RV32ZBKB-NEXT: ret 2273ac93d1fSCraig Topper %4 = add i8 %1, %0 2283ac93d1fSCraig Topper %5 = zext i8 %4 to i16 2293ac93d1fSCraig Topper %6 = shl i16 %5, 8 2303ac93d1fSCraig Topper %7 = zext i8 %2 to i16 2313ac93d1fSCraig Topper %8 = or i16 %6, %7 2323ac93d1fSCraig Topper ret i16 %8 2333ac93d1fSCraig Topper} 2347965a21fSCraig Topper 2357965a21fSCraig Topperdefine void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) { 2367965a21fSCraig Topper; RV32I-LABEL: packh_i16_3: 2377965a21fSCraig Topper; RV32I: # %bb.0: 2387965a21fSCraig Topper; RV32I-NEXT: add a0, a1, a0 2397965a21fSCraig Topper; RV32I-NEXT: slli a0, a0, 8 2407965a21fSCraig Topper; RV32I-NEXT: or a0, a0, a2 2417965a21fSCraig Topper; RV32I-NEXT: sh a0, 0(a3) 2427965a21fSCraig Topper; RV32I-NEXT: ret 2437965a21fSCraig Topper; 2447965a21fSCraig Topper; RV32ZBKB-LABEL: packh_i16_3: 2457965a21fSCraig Topper; RV32ZBKB: # %bb.0: 2467965a21fSCraig Topper; RV32ZBKB-NEXT: add a0, a1, a0 2477965a21fSCraig Topper; RV32ZBKB-NEXT: packh a0, a2, a0 2487965a21fSCraig Topper; RV32ZBKB-NEXT: sh a0, 0(a3) 2497965a21fSCraig Topper; RV32ZBKB-NEXT: ret 2507965a21fSCraig Topper %4 = add i8 %1, %0 2517965a21fSCraig Topper %5 = zext i8 %4 to i16 2527965a21fSCraig Topper %6 = shl i16 %5, 8 2537965a21fSCraig Topper %7 = zext i8 %2 to i16 2547965a21fSCraig Topper %8 = or i16 %6, %7 2557965a21fSCraig Topper store i16 %8, ptr %p 2567965a21fSCraig Topper ret void 2577965a21fSCraig Topper} 258*cad72632SCraig Topper 259*cad72632SCraig Topperdefine i32 @zexth_i32(i32 %a) nounwind { 260*cad72632SCraig Topper; RV32I-LABEL: zexth_i32: 261*cad72632SCraig Topper; RV32I: # %bb.0: 262*cad72632SCraig Topper; RV32I-NEXT: slli a0, a0, 16 263*cad72632SCraig Topper; RV32I-NEXT: srli a0, a0, 16 264*cad72632SCraig Topper; RV32I-NEXT: ret 265*cad72632SCraig Topper; 266*cad72632SCraig Topper; RV32ZBKB-LABEL: zexth_i32: 267*cad72632SCraig Topper; RV32ZBKB: # %bb.0: 268*cad72632SCraig Topper; RV32ZBKB-NEXT: zext.h a0, a0 269*cad72632SCraig Topper; RV32ZBKB-NEXT: ret 270*cad72632SCraig Topper %and = and i32 %a, 65535 271*cad72632SCraig Topper ret i32 %and 272*cad72632SCraig Topper} 273*cad72632SCraig Topper 274*cad72632SCraig Topperdefine i64 @zexth_i64(i64 %a) nounwind { 275*cad72632SCraig Topper; RV32I-LABEL: zexth_i64: 276*cad72632SCraig Topper; RV32I: # %bb.0: 277*cad72632SCraig Topper; RV32I-NEXT: slli a0, a0, 16 278*cad72632SCraig Topper; RV32I-NEXT: srli a0, a0, 16 279*cad72632SCraig Topper; RV32I-NEXT: li a1, 0 280*cad72632SCraig Topper; RV32I-NEXT: ret 281*cad72632SCraig Topper; 282*cad72632SCraig Topper; RV32ZBKB-LABEL: zexth_i64: 283*cad72632SCraig Topper; RV32ZBKB: # %bb.0: 284*cad72632SCraig Topper; RV32ZBKB-NEXT: zext.h a0, a0 285*cad72632SCraig Topper; RV32ZBKB-NEXT: li a1, 0 286*cad72632SCraig Topper; RV32ZBKB-NEXT: ret 287*cad72632SCraig Topper %and = and i64 %a, 65535 288*cad72632SCraig Topper ret i64 %and 289*cad72632SCraig Topper} 290*cad72632SCraig Topper 291*cad72632SCraig Topperdefine i32 @zext_i16_to_i32(i16 %a) nounwind { 292*cad72632SCraig Topper; RV32I-LABEL: zext_i16_to_i32: 293*cad72632SCraig Topper; RV32I: # %bb.0: 294*cad72632SCraig Topper; RV32I-NEXT: slli a0, a0, 16 295*cad72632SCraig Topper; RV32I-NEXT: srli a0, a0, 16 296*cad72632SCraig Topper; RV32I-NEXT: ret 297*cad72632SCraig Topper; 298*cad72632SCraig Topper; RV32ZBKB-LABEL: zext_i16_to_i32: 299*cad72632SCraig Topper; RV32ZBKB: # %bb.0: 300*cad72632SCraig Topper; RV32ZBKB-NEXT: zext.h a0, a0 301*cad72632SCraig Topper; RV32ZBKB-NEXT: ret 302*cad72632SCraig Topper %1 = zext i16 %a to i32 303*cad72632SCraig Topper ret i32 %1 304*cad72632SCraig Topper} 305*cad72632SCraig Topper 306*cad72632SCraig Topperdefine i64 @zext_i16_to_i64(i16 %a) nounwind { 307*cad72632SCraig Topper; RV32I-LABEL: zext_i16_to_i64: 308*cad72632SCraig Topper; RV32I: # %bb.0: 309*cad72632SCraig Topper; RV32I-NEXT: slli a0, a0, 16 310*cad72632SCraig Topper; RV32I-NEXT: srli a0, a0, 16 311*cad72632SCraig Topper; RV32I-NEXT: li a1, 0 312*cad72632SCraig Topper; RV32I-NEXT: ret 313*cad72632SCraig Topper; 314*cad72632SCraig Topper; RV32ZBKB-LABEL: zext_i16_to_i64: 315*cad72632SCraig Topper; RV32ZBKB: # %bb.0: 316*cad72632SCraig Topper; RV32ZBKB-NEXT: zext.h a0, a0 317*cad72632SCraig Topper; RV32ZBKB-NEXT: li a1, 0 318*cad72632SCraig Topper; RV32ZBKB-NEXT: ret 319*cad72632SCraig Topper %1 = zext i16 %a to i64 320*cad72632SCraig Topper ret i64 %1 321*cad72632SCraig Topper} 322