Compiler projects using llvm
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefix=RV64I
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbp -verify-machineinstrs < %s \
; RUN:   | FileCheck %s -check-prefix=RV64ZBP

define signext i32 @gorc1_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc1_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc1_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 1
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 1
  %shl = and i32 %and, -1431655766
  %and1 = lshr i32 %a, 1
  %shr = and i32 %and1, 1431655765
  %or = or i32 %shr, %a
  %or2 = or i32 %or, %shl
  ret i32 %or2
}

define i64 @gorc1_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc1_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI1_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI1_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI1_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI1_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 1
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc1_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc.p a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 1
  %shl = and i64 %and, -6148914691236517206
  %and1 = lshr i64 %a, 1
  %shr = and i64 %and1, 6148914691236517205
  %or = or i64 %shr, %a
  %or2 = or i64 %or, %shl
  ret i64 %or2
}

define signext i32 @gorc2_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc2_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    lui a3, 209715
; RV64I-NEXT:    addiw a3, a3, 819
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc2_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 2
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 2
  %shl = and i32 %and, -858993460
  %and1 = lshr i32 %a, 2
  %shr = and i32 %and1, 858993459
  %or = or i32 %shr, %a
  %or2 = or i32 %or, %shl
  ret i32 %or2
}

define i64 @gorc2_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc2_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI3_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI3_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI3_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI3_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc2_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc2.n a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 2
  %shl = and i64 %and, -3689348814741910324
  %and1 = lshr i64 %a, 2
  %shr = and i64 %and1, 3689348814741910323
  %or = or i64 %shr, %a
  %or2 = or i64 %or, %shl
  ret i64 %or2
}

define signext i32 @gorc3_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc3_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    lui a3, 209715
; RV64I-NEXT:    addiw a3, a3, 819
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc3_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 3
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1b, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  ret i32 %or2b
}

define i64 @gorc3_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc3_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI5_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI5_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI5_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI5_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 1
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI5_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI5_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI5_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI5_3)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc3_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc.n a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1b, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  ret i64 %or2b
}

define signext i32 @gorc4_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc4_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc4_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 4
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 4
  %shl = and i32 %and, -252645136
  %and1 = lshr i32 %a, 4
  %shr = and i32 %and1, 252645135
  %or = or i32 %shr, %a
  %or2 = or i32 %or, %shl
  ret i32 %or2
}

define i64 @gorc4_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc4_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI7_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI7_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI7_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI7_1)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 4
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc4_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc4.b a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 4
  %shl = and i64 %and, -1085102592571150096
  %and1 = lshr i64 %a, 4
  %shr = and i64 %and1, 1085102592571150095
  %or = or i64 %shr, %a
  %or2 = or i64 %or, %shl
  ret i64 %or2
}

define signext i32 @gorc5_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc5_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc5_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 5
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 4
  %shl2 = and i32 %and2, -252645136
  %and2b = lshr i32 %or1b, 4
  %shr2 = and i32 %and2b, 252645135
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  ret i32 %or2b
}

define i64 @gorc5_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc5_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI9_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI9_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI9_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI9_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 1
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI9_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI9_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI9_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI9_3)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 4
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc5_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorci a0, a0, 5
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 4
  %shl2 = and i64 %and2, -1085102592571150096
  %and2b = lshr i64 %or1b, 4
  %shr2 = and i64 %and2b, 1085102592571150095
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  ret i64 %or2b
}

define signext i32 @gorc6_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc6_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    lui a3, 209715
; RV64I-NEXT:    addiw a3, a3, 819
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc6_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 6
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 2
  %shl1 = and i32 %and1, -858993460
  %and1b = lshr i32 %a, 2
  %shr1 = and i32 %and1b, 858993459
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 4
  %shl2 = and i32 %and2, -252645136
  %and2b = lshr i32 %or1b, 4
  %shr2 = and i32 %and2b, 252645135
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  ret i32 %or2b
}

define i64 @gorc6_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc6_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI11_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI11_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI11_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI11_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI11_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI11_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI11_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI11_3)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 4
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc6_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc2.b a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 2
  %shl1 = and i64 %and1, -3689348814741910324
  %and1b = lshr i64 %a, 2
  %shr1 = and i64 %and1b, 3689348814741910323
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 4
  %shl2 = and i64 %and2, -1085102592571150096
  %and2b = lshr i64 %or1b, 4
  %shr2 = and i64 %and2b, 1085102592571150095
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  ret i64 %or2b
}

define signext i32 @gorc7_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc7_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    lui a3, 209715
; RV64I-NEXT:    addiw a3, a3, 819
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slli a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    sext.w a0, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc7_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 7
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1b, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  %and3 = shl i32 %or2b, 4
  %shl3 = and i32 %and3, -252645136
  %and3b = lshr i32 %or2b, 4
  %shr3 = and i32 %and3b, 252645135
  %or3 = or i32 %shr3, %or2b
  %or3b = or i32 %or3, %shl3
  ret i32 %or3b
}

define i64 @gorc7_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc7_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI13_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI13_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI13_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI13_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 1
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI13_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI13_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI13_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI13_3)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI13_4)
; RV64I-NEXT:    ld a1, %lo(.LCPI13_4)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI13_5)
; RV64I-NEXT:    ld a2, %lo(.LCPI13_5)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 4
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc7_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc.b a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1b, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  %and3 = shl i64 %or2b, 4
  %shl3 = and i64 %and3, -1085102592571150096
  %and3b = lshr i64 %or2b, 4
  %shr3 = and i64 %and3b, 1085102592571150095
  %or3 = or i64 %shr3, %or2b
  %or3b = or i64 %or3, %shl3
  ret i64 %or3b
}

define signext i32 @gorc8_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc8_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 8
; RV64I-NEXT:    lui a2, 1044496
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    addiw a3, a3, 255
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc8_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 8
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 8
  %shl = and i32 %and, -16711936
  %and1 = lshr i32 %a, 8
  %shr = and i32 %and1, 16711935
  %or = or i32 %shr, %a
  %or2 = or i32 %or, %shl
  ret i32 %or2
}

define i64 @gorc8_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc8_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI15_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI15_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI15_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI15_1)(a2)
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 8
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc8_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc8.h a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 8
  %shl = and i64 %and, -71777214294589696
  %and1 = lshr i64 %a, 8
  %shr = and i64 %and1, 71777214294589695
  %or = or i64 %shr, %a
  %or2 = or i64 %or, %shl
  ret i64 %or2
}

define signext i32 @gorc12_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc12_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 8
; RV64I-NEXT:    lui a2, 1044496
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    addiw a3, a3, 255
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc12_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 12
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 4
  %shl1 = and i32 %and1, -252645136
  %and1b = lshr i32 %a, 4
  %shr1 = and i32 %and1b, 252645135
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 8
  %shl2 = and i32 %and2, -16711936
  %and2b = lshr i32 %or1b, 8
  %shr2 = and i32 %and2b, 16711935
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  ret i32 %or2b
}

define i64 @gorc12_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc12_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI17_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI17_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI17_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI17_1)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 4
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI17_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI17_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI17_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI17_3)(a2)
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 8
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc12_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc4.h a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 4
  %shl1 = and i64 %and1, -1085102592571150096
  %and1b = lshr i64 %a, 4
  %shr1 = and i64 %and1b, 1085102592571150095
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 8
  %shl2 = and i64 %and2, -71777214294589696
  %and2b = lshr i64 %or1b, 8
  %shr2 = and i64 %and2b, 71777214294589695
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  ret i64 %or2b
}

define signext i32 @gorc14_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc14_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    lui a3, 209715
; RV64I-NEXT:    addiw a3, a3, 819
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slli a1, a0, 8
; RV64I-NEXT:    lui a2, 1044496
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    addiw a3, a3, 255
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    sext.w a0, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc14_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 14
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 2
  %shl1 = and i32 %and1, -858993460
  %and1b = lshr i32 %a, 2
  %shr1 = and i32 %and1b, 858993459
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 4
  %shl2 = and i32 %and2, -252645136
  %and2b = lshr i32 %or1b, 4
  %shr2 = and i32 %and2b, 252645135
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  %and3 = shl i32 %or2b, 8
  %shl3 = and i32 %and3, -16711936
  %and3b = lshr i32 %or2b, 8
  %shr3 = and i32 %and3b, 16711935
  %or3 = or i32 %shr3, %or2b
  %or3b = or i32 %or3, %shl3
  ret i32 %or3b
}

define i64 @gorc14_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc14_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI19_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI19_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI19_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI19_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI19_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI19_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI19_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI19_3)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 4
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI19_4)
; RV64I-NEXT:    ld a1, %lo(.LCPI19_4)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI19_5)
; RV64I-NEXT:    ld a2, %lo(.LCPI19_5)(a2)
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 8
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc14_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc2.h a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 2
  %shl1 = and i64 %and1, -3689348814741910324
  %and1b = lshr i64 %a, 2
  %shr1 = and i64 %and1b, 3689348814741910323
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 4
  %shl2 = and i64 %and2, -1085102592571150096
  %and2b = lshr i64 %or1b, 4
  %shr2 = and i64 %and2b, 1085102592571150095
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  %and3 = shl i64 %or2b, 8
  %shl3 = and i64 %and3, -71777214294589696
  %and3b = lshr i64 %or2b, 8
  %shr3 = and i64 %and3b, 71777214294589695
  %or3 = or i64 %shr3, %or2b
  %or3b = or i64 %or3, %shl3
  ret i64 %or3b
}

define signext i32 @gorc16_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc16_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 16
; RV64I-NEXT:    srliw a2, a0, 16
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc16_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 16
; RV64ZBP-NEXT:    ret
  %shl = shl i32 %a, 16
  %shr = lshr i32 %a, 16
  %or = or i32 %shr, %a
  %or2 = or i32 %or, %shl
  ret i32 %or2
}

define i32 @gorc16_rotl_i32(i32 %a) nounwind {
; RV64I-LABEL: gorc16_rotl_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a1, a0, 16
; RV64I-NEXT:    slliw a2, a0, 16
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc16_rotl_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc16.w a0, a0
; RV64ZBP-NEXT:    ret
  %rot = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 16)
  %or = or i32 %rot, %a
  ret i32 %or
}

define i32 @gorc16_rotr_i32(i32 %a) nounwind {
; RV64I-LABEL: gorc16_rotr_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 16
; RV64I-NEXT:    srliw a2, a0, 16
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc16_rotr_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc16.w a0, a0
; RV64ZBP-NEXT:    ret
  %rot = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 16)
  %or = or i32 %rot, %a
  ret i32 %or
}

define i64 @gorc16_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc16_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 16
; RV64I-NEXT:    lui a2, 983041
; RV64I-NEXT:    slli a3, a2, 4
; RV64I-NEXT:    addi a3, a3, -1
; RV64I-NEXT:    slli a3, a3, 16
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    srli a3, a0, 16
; RV64I-NEXT:    slli a2, a2, 20
; RV64I-NEXT:    addi a2, a2, -1
; RV64I-NEXT:    srli a2, a2, 16
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc16_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc16.w a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 16
  %shl = and i64 %and, -281470681808896
  %and1 = lshr i64 %a, 16
  %shr = and i64 %and1, 281470681808895
  %or = or i64 %shr, %a
  %or2 = or i64 %or, %shl
  ret i64 %or2
}

define i64 @gorc32(i64 %a) nounwind {
; RV64I-LABEL: gorc32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 32
; RV64I-NEXT:    srli a2, a0, 32
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc32 a0, a0
; RV64ZBP-NEXT:    ret
  %shl = shl i64 %a, 32
  %shr = lshr i64 %a, 32
  %or = or i64 %shr, %a
  %or2 = or i64 %or, %shl
  ret i64 %or2
}

; gorc2, gorc2 -> gorc2
define signext i32 @gorc2b_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc2b_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    lui a4, 209715
; RV64I-NEXT:    addiw a4, a4, 819
; RV64I-NEXT:    and a3, a3, a4
; RV64I-NEXT:    or a0, a3, a0
; RV64I-NEXT:    or a1, a0, a1
; RV64I-NEXT:    slliw a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    srli a2, a1, 2
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc2b_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    srliw a1, a0, 2
; RV64ZBP-NEXT:    or a1, a1, a0
; RV64ZBP-NEXT:    orc2.n a0, a0
; RV64ZBP-NEXT:    slli a1, a1, 2
; RV64ZBP-NEXT:    lui a2, 838861
; RV64ZBP-NEXT:    addiw a2, a2, -820
; RV64ZBP-NEXT:    and a1, a1, a2
; RV64ZBP-NEXT:    srli a2, a0, 2
; RV64ZBP-NEXT:    lui a3, 209715
; RV64ZBP-NEXT:    addiw a3, a3, 819
; RV64ZBP-NEXT:    and a2, a2, a3
; RV64ZBP-NEXT:    or a0, a2, a0
; RV64ZBP-NEXT:    or a0, a0, a1
; RV64ZBP-NEXT:    sext.w a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 2
  %shl1 = and i32 %and1, -858993460
  %and1b = lshr i32 %a, 2
  %shr1 = and i32 %and1b, 858993459
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1b, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  ret i32 %or2b
}

; gorc2, gorc2 -> gorc2
define i64 @gorc2b_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc2b_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI26_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI26_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI26_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI26_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a3, a3, a1
; RV64I-NEXT:    srli a4, a0, 2
; RV64I-NEXT:    and a4, a4, a2
; RV64I-NEXT:    or a0, a4, a0
; RV64I-NEXT:    or a3, a0, a3
; RV64I-NEXT:    slli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a1
; RV64I-NEXT:    srli a1, a3, 2
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    or a1, a1, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc2b_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    srli a1, a0, 2
; RV64ZBP-NEXT:    or a1, a1, a0
; RV64ZBP-NEXT:    orc2.n a0, a0
; RV64ZBP-NEXT:    lui a2, %hi(.LCPI26_0)
; RV64ZBP-NEXT:    ld a2, %lo(.LCPI26_0)(a2)
; RV64ZBP-NEXT:    lui a3, %hi(.LCPI26_1)
; RV64ZBP-NEXT:    ld a3, %lo(.LCPI26_1)(a3)
; RV64ZBP-NEXT:    slli a1, a1, 2
; RV64ZBP-NEXT:    and a1, a1, a2
; RV64ZBP-NEXT:    srli a2, a0, 2
; RV64ZBP-NEXT:    and a2, a2, a3
; RV64ZBP-NEXT:    or a0, a2, a0
; RV64ZBP-NEXT:    or a0, a0, a1
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 2
  %shl1 = and i64 %and1, -3689348814741910324
  %and1b = lshr i64 %a, 2
  %shr1 = and i64 %and1b, 3689348814741910323
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1b, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  ret i64 %or2b
}

; gorc1, gorc2, gorc1 -> gorc2
define signext i32 @gorc3b_i32(i32 signext %a) nounwind {
; RV64I-LABEL: gorc3b_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a3, a0, 1
; RV64I-NEXT:    lui a4, 349525
; RV64I-NEXT:    addiw a4, a4, 1365
; RV64I-NEXT:    and a3, a3, a4
; RV64I-NEXT:    or a0, a3, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a3, 838861
; RV64I-NEXT:    addiw a3, a3, -820
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    srli a3, a0, 2
; RV64I-NEXT:    lui a5, 209715
; RV64I-NEXT:    addiw a5, a5, 819
; RV64I-NEXT:    and a3, a3, a5
; RV64I-NEXT:    or a0, a3, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slli a1, a0, 1
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    sext.w a0, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc3b_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    gorciw a0, a0, 3
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shr1, %a
  %or1b = or i32 %or1, %shl1
  %and2 = shl i32 %or1b, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1b, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shr2, %or1b
  %or2b = or i32 %or2, %shl2
  %and3 = shl i32 %or2b, 1
  %shl3 = and i32 %and3, -1431655766
  %and3b = lshr i32 %or2b, 1
  %shr3 = and i32 %and3b, 1431655765
  %or3 = or i32 %shr3, %or2b
  %or3b = or i32 %or3, %shl3
  ret i32 %or3b
}

; gorc1, gorc2, gorc1 -> gorc2
define i64 @gorc3b_i64(i64 %a) nounwind {
; RV64I-LABEL: gorc3b_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI28_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI28_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI28_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI28_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a3, a3, a1
; RV64I-NEXT:    srli a4, a0, 1
; RV64I-NEXT:    and a4, a4, a2
; RV64I-NEXT:    or a0, a4, a0
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    lui a3, %hi(.LCPI28_2)
; RV64I-NEXT:    ld a3, %lo(.LCPI28_2)(a3)
; RV64I-NEXT:    lui a4, %hi(.LCPI28_3)
; RV64I-NEXT:    ld a4, %lo(.LCPI28_3)(a4)
; RV64I-NEXT:    slli a5, a0, 2
; RV64I-NEXT:    and a3, a5, a3
; RV64I-NEXT:    srli a5, a0, 2
; RV64I-NEXT:    and a4, a5, a4
; RV64I-NEXT:    or a0, a4, a0
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a3, a0, 1
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc3b_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc.n a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shr1, %a
  %or1b = or i64 %or1, %shl1
  %and2 = shl i64 %or1b, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1b, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shr2, %or1b
  %or2b = or i64 %or2, %shl2
  %and3 = shl i64 %or2b, 1
  %shl3 = and i64 %and3, -6148914691236517206
  %and3b = lshr i64 %or2b, 1
  %shr3 = and i64 %and3b, 6148914691236517205
  %or3 = or i64 %shr3, %or2b
  %or3b = or i64 %or3, %shl3
  ret i64 %or3b
}

define i64 @gorc32_rotl(i64 %a) nounwind {
; RV64I-LABEL: gorc32_rotl:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 32
; RV64I-NEXT:    slli a2, a0, 32
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc32_rotl:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc32 a0, a0
; RV64ZBP-NEXT:    ret
  %rot = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 32)
  %or = or i64 %rot, %a
  ret i64 %or
}

define i64 @gorc32_rotr(i64 %a) nounwind {
; RV64I-LABEL: gorc32_rotr:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 32
; RV64I-NEXT:    srli a2, a0, 32
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: gorc32_rotr:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    orc32 a0, a0
; RV64ZBP-NEXT:    ret
  %rot = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 32)
  %or = or i64 %rot, %a
  ret i64 %or
}

define signext i32 @grev1_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev1_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev1_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 1
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 1
  %shl = and i32 %and, -1431655766
  %and1 = lshr i32 %a, 1
  %shr = and i32 %and1, 1431655765
  %or = or i32 %shl, %shr
  ret i32 %or
}

define i64 @grev1_i64(i64 %a) nounwind {
; RV64I-LABEL: grev1_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI32_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI32_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI32_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI32_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev1_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.p a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 1
  %shl = and i64 %and, -6148914691236517206
  %and1 = lshr i64 %a, 1
  %shr = and i64 %and1, 6148914691236517205
  %or = or i64 %shl, %shr
  ret i64 %or
}

define signext i32 @grev2_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev2_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev2_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 2
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 2
  %shl = and i32 %and, -858993460
  %and1 = lshr i32 %a, 2
  %shr = and i32 %and1, 858993459
  %or = or i32 %shl, %shr
  ret i32 %or
}

define i64 @grev2_i64(i64 %a) nounwind {
; RV64I-LABEL: grev2_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI34_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI34_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI34_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI34_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev2_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev2.n a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 2
  %shl = and i64 %and, -3689348814741910324
  %and1 = lshr i64 %a, 2
  %shr = and i64 %and1, 3689348814741910323
  %or = or i64 %shl, %shr
  ret i64 %or
}

define signext i32 @grev3_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev3_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev3_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 3
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shl2, %shr2
  ret i32 %or2
}

define i64 @grev3_i64(i64 %a) nounwind {
; RV64I-LABEL: grev3_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI36_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI36_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI36_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI36_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI36_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI36_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI36_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI36_3)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev3_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.n a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shl2, %shr2
  ret i64 %or2
}

define signext i32 @grev4_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev4_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev4_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 4
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 4
  %shl = and i32 %and, -252645136
  %and1 = lshr i32 %a, 4
  %shr = and i32 %and1, 252645135
  %or = or i32 %shl, %shr
  ret i32 %or
}

define i64 @grev4_i64(i64 %a) nounwind {
; RV64I-LABEL: grev4_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI38_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI38_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI38_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI38_1)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev4_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev4.b a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 4
  %shl = and i64 %and, -1085102592571150096
  %and1 = lshr i64 %a, 4
  %shr = and i64 %and1, 1085102592571150095
  %or = or i64 %shl, %shr
  ret i64 %or
}

define signext i32 @grev5_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev5_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev5_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 5
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 4
  %shl2 = and i32 %and2, -252645136
  %and2b = lshr i32 %or1, 4
  %shr2 = and i32 %and2b, 252645135
  %or2 = or i32 %shl2, %shr2
  ret i32 %or2
}

define i64 @grev5_i64(i64 %a) nounwind {
; RV64I-LABEL: grev5_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI40_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI40_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI40_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI40_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI40_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI40_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI40_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI40_3)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev5_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    grevi a0, a0, 5
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shl1, %shr1

  %and2 = shl i64 %or1, 4
  %shl2 = and i64 %and2, -1085102592571150096
  %and2b = lshr i64 %or1, 4
  %shr2 = and i64 %and2b, 1085102592571150095
  %or2 = or i64 %shl2, %shr2
  ret i64 %or2
}

define signext i32 @grev6_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev6_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev6_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 6
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 2
  %shl1 = and i32 %and1, -858993460
  %and1b = lshr i32 %a, 2
  %shr1 = and i32 %and1b, 858993459
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 4
  %shl2 = and i32 %and2, -252645136
  %and2b = lshr i32 %or1, 4
  %shr2 = and i32 %and2b, 252645135
  %or2 = or i32 %shl2, %shr2
  ret i32 %or2
}

define i64 @grev6_i64(i64 %a) nounwind {
; RV64I-LABEL: grev6_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI42_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI42_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI42_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI42_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI42_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI42_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI42_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI42_3)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev6_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev2.b a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 2
  %shl1 = and i64 %and1, -3689348814741910324
  %and1b = lshr i64 %a, 2
  %shr1 = and i64 %and1b, 3689348814741910323
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 4
  %shl2 = and i64 %and2, -1085102592571150096
  %and2b = lshr i64 %or1, 4
  %shr2 = and i64 %and2b, 1085102592571150095
  %or2 = or i64 %shl2, %shr2
  ret i64 %or2
}

define signext i32 @grev7_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev7_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev7_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 7
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shl2, %shr2
  %and3 = shl i32 %or2, 4
  %shl3 = and i32 %and3, -252645136
  %and3b = lshr i32 %or2, 4
  %shr3 = and i32 %and3b, 252645135
  %or3 = or i32 %shl3, %shr3
  ret i32 %or3
}

define zeroext i32 @grev7_i32_zext(i32 zeroext %a) nounwind {
; RV64I-LABEL: grev7_i32_zext:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slli a1, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    slli a3, a2, 4
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev7_i32_zext:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.b a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shl2, %shr2
  %and3 = shl i32 %or2, 4
  %shl3 = and i32 %and3, -252645136
  %and3b = lshr i32 %or2, 4
  %shr3 = and i32 %and3b, 252645135
  %or3 = or i32 %shl3, %shr3
  ret i32 %or3
}

define i64 @grev7_i64(i64 %a) nounwind {
; RV64I-LABEL: grev7_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI45_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI45_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI45_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI45_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI45_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI45_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI45_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI45_3)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI45_4)
; RV64I-NEXT:    ld a1, %lo(.LCPI45_4)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI45_5)
; RV64I-NEXT:    ld a2, %lo(.LCPI45_5)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev7_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.b a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shl2, %shr2
  %and3 = shl i64 %or2, 4
  %shl3 = and i64 %and3, -1085102592571150096
  %and3b = lshr i64 %or2, 4
  %shr3 = and i64 %and3b, 1085102592571150095
  %or3 = or i64 %shl3, %shr3
  ret i64 %or3
}

define signext i32 @grev8_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev8_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 8
; RV64I-NEXT:    lui a2, 1044496
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    lui a2, 4080
; RV64I-NEXT:    addiw a2, a2, 255
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev8_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 8
; RV64ZBP-NEXT:    ret
  %and = shl i32 %a, 8
  %shl = and i32 %and, -16711936
  %and1 = lshr i32 %a, 8
  %shr = and i32 %and1, 16711935
  %or = or i32 %shl, %shr
  ret i32 %or
}

define i64 @grev8_i64(i64 %a) nounwind {
; RV64I-LABEL: grev8_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI47_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI47_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI47_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI47_1)(a2)
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev8_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev8.h a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 8
  %shl = and i64 %and, -71777214294589696
  %and1 = lshr i64 %a, 8
  %shr = and i64 %and1, 71777214294589695
  %or = or i64 %shl, %shr
  ret i64 %or
}

define signext i32 @grev12_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev12_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 8
; RV64I-NEXT:    lui a2, 1044496
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    lui a2, 4080
; RV64I-NEXT:    addiw a2, a2, 255
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev12_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 12
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 4
  %shl1 = and i32 %and1, -252645136
  %and1b = lshr i32 %a, 4
  %shr1 = and i32 %and1b, 252645135
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 8
  %shl2 = and i32 %and2, -16711936
  %and2b = lshr i32 %or1, 8
  %shr2 = and i32 %and2b, 16711935
  %or2 = or i32 %shl2, %shr2
  ret i32 %or2
}

define i64 @grev12_i64(i64 %a) nounwind {
; RV64I-LABEL: grev12_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI49_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI49_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI49_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI49_1)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI49_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI49_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI49_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI49_3)(a2)
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev12_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev4.h a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 4
  %shl1 = and i64 %and1, -1085102592571150096
  %and1b = lshr i64 %a, 4
  %shr1 = and i64 %and1b, 1085102592571150095
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 8
  %shl2 = and i64 %and2, -71777214294589696
  %and2b = lshr i64 %or1, 8
  %shr2 = and i64 %and2b, 71777214294589695
  %or2 = or i64 %shl2, %shr2
  ret i64 %or2
}

define signext i32 @grev14_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev14_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 4
; RV64I-NEXT:    lui a2, 986895
; RV64I-NEXT:    addiw a2, a2, 240
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 8
; RV64I-NEXT:    lui a2, 1044496
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    lui a2, 4080
; RV64I-NEXT:    addiw a2, a2, 255
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev14_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 14
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 2
  %shl1 = and i32 %and1, -858993460
  %and1b = lshr i32 %a, 2
  %shr1 = and i32 %and1b, 858993459
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 4
  %shl2 = and i32 %and2, -252645136
  %and2b = lshr i32 %or1, 4
  %shr2 = and i32 %and2b, 252645135
  %or2 = or i32 %shl2, %shr2
  %and3 = shl i32 %or2, 8
  %shl3 = and i32 %and3, -16711936
  %and3b = lshr i32 %or2, 8
  %shr3 = and i32 %and3b, 16711935
  %or3 = or i32 %shl3, %shr3
  ret i32 %or3
}

define i64 @grev14_i64(i64 %a) nounwind {
; RV64I-LABEL: grev14_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI51_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI51_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI51_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI51_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI51_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI51_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI51_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI51_3)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI51_4)
; RV64I-NEXT:    ld a1, %lo(.LCPI51_4)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI51_5)
; RV64I-NEXT:    ld a2, %lo(.LCPI51_5)(a2)
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev14_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev2.h a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 2
  %shl1 = and i64 %and1, -3689348814741910324
  %and1b = lshr i64 %a, 2
  %shr1 = and i64 %and1b, 3689348814741910323
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 4
  %shl2 = and i64 %and2, -1085102592571150096
  %and2b = lshr i64 %or1, 4
  %shr2 = and i64 %and2b, 1085102592571150095
  %or2 = or i64 %shl2, %shr2
  %and3 = shl i64 %or2, 8
  %shl3 = and i64 %and3, -71777214294589696
  %and3b = lshr i64 %or2, 8
  %shr3 = and i64 %and3b, 71777214294589695
  %or3 = or i64 %shl3, %shr3
  ret i64 %or3
}

define signext i32 @grev16_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev16_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a1, a0, 16
; RV64I-NEXT:    slliw a0, a0, 16
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev16_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    roriw a0, a0, 16
; RV64ZBP-NEXT:    ret
  %shl = shl i32 %a, 16
  %shr = lshr i32 %a, 16
  %or = or i32 %shl, %shr
  ret i32 %or
}

declare i32 @llvm.fshl.i32(i32, i32, i32)
declare i32 @llvm.fshr.i32(i32, i32, i32)

define signext i32 @grev16_i32_fshl(i32 signext %a) nounwind {
; RV64I-LABEL: grev16_i32_fshl:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a1, a0, 16
; RV64I-NEXT:    slliw a0, a0, 16
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev16_i32_fshl:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    roriw a0, a0, 16
; RV64ZBP-NEXT:    ret
  %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 16)
  ret i32 %or
}

define signext i32 @grev16_i32_fshr(i32 signext %a) nounwind {
; RV64I-LABEL: grev16_i32_fshr:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 16
; RV64I-NEXT:    srliw a0, a0, 16
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev16_i32_fshr:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    roriw a0, a0, 16
; RV64ZBP-NEXT:    ret
  %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 16)
  ret i32 %or
}

define i64 @grev16_i64(i64 %a) nounwind {
; RV64I-LABEL: grev16_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 16
; RV64I-NEXT:    lui a2, 983041
; RV64I-NEXT:    slli a3, a2, 4
; RV64I-NEXT:    addi a3, a3, -1
; RV64I-NEXT:    slli a3, a3, 16
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    srli a0, a0, 16
; RV64I-NEXT:    slli a2, a2, 20
; RV64I-NEXT:    addi a2, a2, -1
; RV64I-NEXT:    srli a2, a2, 16
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev16_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev16.w a0, a0
; RV64ZBP-NEXT:    ret
  %and = shl i64 %a, 16
  %shl = and i64 %and, -281470681808896
  %and1 = lshr i64 %a, 16
  %shr = and i64 %and1, 281470681808895
  %or = or i64 %shl, %shr
  ret i64 %or
}

define i64 @grev32(i64 %a) nounwind {
; RV64I-LABEL: grev32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 32
; RV64I-NEXT:    slli a0, a0, 32
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rori a0, a0, 32
; RV64ZBP-NEXT:    ret
  %shl = shl i64 %a, 32
  %shr = lshr i64 %a, 32
  %or = or i64 %shl, %shr
  ret i64 %or
}

define signext i32 @grev3b_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev3b_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a2, 838861
; RV64I-NEXT:    addiw a2, a2, -820
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev3b_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 3
; RV64ZBP-NEXT:    ret
  %and2 = shl i32 %a, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %a, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shl2, %shr2
  %and1 = shl i32 %or2, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %or2, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  ret i32 %or1
}

define i64 @grev3b_i64(i64 %a) nounwind {
; RV64I-LABEL: grev3b_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI58_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI58_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI58_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI58_1)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    lui a1, %hi(.LCPI58_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI58_2)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI58_3)
; RV64I-NEXT:    ld a2, %lo(.LCPI58_3)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev3b_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.n a0, a0
; RV64ZBP-NEXT:    ret
  %and2 = shl i64 %a, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %a, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shl2, %shr2
  %and1 = shl i64 %or2, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %or2, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shl1, %shr1
  ret i64 %or1
}

; grev1, grev2, grev1 -> grev2
define signext i32 @grev2b_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev2b_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a4, 838861
; RV64I-NEXT:    addiw a4, a4, -820
; RV64I-NEXT:    and a1, a1, a4
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a4, 209715
; RV64I-NEXT:    addiw a4, a4, 819
; RV64I-NEXT:    and a0, a0, a4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev2b_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 2
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shl2, %shr2
  %and3 = shl i32 %or2, 1
  %shl3 = and i32 %and3, -1431655766
  %and3b = lshr i32 %or2, 1
  %shr3 = and i32 %and3b, 1431655765
  %or3 = or i32 %shl3, %shr3
  ret i32 %or3
}

; grev1, grev2, grev1 -> grev2
define i64 @grev2b_i64(i64 %a) nounwind {
; RV64I-LABEL: grev2b_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI60_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI60_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI60_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI60_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a3, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a3, a0
; RV64I-NEXT:    lui a3, %hi(.LCPI60_2)
; RV64I-NEXT:    ld a3, %lo(.LCPI60_2)(a3)
; RV64I-NEXT:    lui a4, %hi(.LCPI60_3)
; RV64I-NEXT:    ld a4, %lo(.LCPI60_3)(a4)
; RV64I-NEXT:    slli a5, a0, 2
; RV64I-NEXT:    and a3, a5, a3
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a4
; RV64I-NEXT:    or a0, a3, a0
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev2b_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev2.n a0, a0
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shl2, %shr2
  %and3 = shl i64 %or2, 1
  %shl3 = and i64 %and3, -6148914691236517206
  %and3b = lshr i64 %or2, 1
  %shr3 = and i64 %and3b, 6148914691236517205
  %or3 = or i64 %shl3, %shr3
  ret i64 %or3
}

; grev1, grev2, grev1, grev2 -> identity
define signext i32 @grev0_i32(i32 signext %a) nounwind {
; RV64I-LABEL: grev0_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    lui a2, 699051
; RV64I-NEXT:    addiw a2, a2, -1366
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    lui a4, 838861
; RV64I-NEXT:    addiw a4, a4, -820
; RV64I-NEXT:    and a1, a1, a4
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a5, 209715
; RV64I-NEXT:    addiw a5, a5, 819
; RV64I-NEXT:    and a0, a0, a5
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 1
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slliw a1, a0, 2
; RV64I-NEXT:    and a1, a1, a4
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a5
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev0_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    ret
  %and1 = shl i32 %a, 1
  %shl1 = and i32 %and1, -1431655766
  %and1b = lshr i32 %a, 1
  %shr1 = and i32 %and1b, 1431655765
  %or1 = or i32 %shl1, %shr1
  %and2 = shl i32 %or1, 2
  %shl2 = and i32 %and2, -858993460
  %and2b = lshr i32 %or1, 2
  %shr2 = and i32 %and2b, 858993459
  %or2 = or i32 %shl2, %shr2
  %and3 = shl i32 %or2, 1
  %shl3 = and i32 %and3, -1431655766
  %and3b = lshr i32 %or2, 1
  %shr3 = and i32 %and3b, 1431655765
  %or3 = or i32 %shl3, %shr3
  %and4 = shl i32 %or3, 2
  %shl4 = and i32 %and4, -858993460
  %and4b = lshr i32 %or3, 2
  %shr4 = and i32 %and4b, 858993459
  %or4 = or i32 %shl4, %shr4
  ret i32 %or4
}

; grev1, grev2, grev1, grev2 -> identity
define i64 @grev0_i64(i64 %a) nounwind {
; RV64I-LABEL: grev0_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI62_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI62_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI62_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI62_1)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a3, a3, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a3, a0
; RV64I-NEXT:    lui a3, %hi(.LCPI62_2)
; RV64I-NEXT:    ld a3, %lo(.LCPI62_2)(a3)
; RV64I-NEXT:    lui a4, %hi(.LCPI62_3)
; RV64I-NEXT:    ld a4, %lo(.LCPI62_3)(a4)
; RV64I-NEXT:    slli a5, a0, 2
; RV64I-NEXT:    and a5, a5, a3
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a4
; RV64I-NEXT:    or a0, a5, a0
; RV64I-NEXT:    slli a5, a0, 1
; RV64I-NEXT:    and a1, a5, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    slli a1, a0, 2
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev0_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    ret
  %and1 = shl i64 %a, 1
  %shl1 = and i64 %and1, -6148914691236517206
  %and1b = lshr i64 %a, 1
  %shr1 = and i64 %and1b, 6148914691236517205
  %or1 = or i64 %shl1, %shr1
  %and2 = shl i64 %or1, 2
  %shl2 = and i64 %and2, -3689348814741910324
  %and2b = lshr i64 %or1, 2
  %shr2 = and i64 %and2b, 3689348814741910323
  %or2 = or i64 %shl2, %shr2
  %and3 = shl i64 %or2, 1
  %shl3 = and i64 %and3, -6148914691236517206
  %and3b = lshr i64 %or2, 1
  %shr3 = and i64 %and3b, 6148914691236517205
  %or3 = or i64 %shl3, %shr3
  %and4 = shl i64 %or3, 2
  %shl4 = and i64 %and4, -3689348814741910324
  %and4b = lshr i64 %or3, 2
  %shr4 = and i64 %and4b, 3689348814741910323
  %or4 = or i64 %shl4, %shr4
  ret i64 %or4
}

declare i64 @llvm.fshl.i64(i64, i64, i64)
declare i64 @llvm.fshr.i64(i64, i64, i64)

define i64 @grev32_fshl(i64 %a) nounwind {
; RV64I-LABEL: grev32_fshl:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 32
; RV64I-NEXT:    slli a0, a0, 32
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev32_fshl:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rori a0, a0, 32
; RV64ZBP-NEXT:    ret
  %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 32)
  ret i64 %or
}

define i64 @grev32_fshr(i64 %a) nounwind {
; RV64I-LABEL: grev32_fshr:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 32
; RV64I-NEXT:    srli a0, a0, 32
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: grev32_fshr:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rori a0, a0, 32
; RV64ZBP-NEXT:    ret
  %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 32)
  ret i64 %or
}

declare i16 @llvm.bswap.i16(i16)

define zeroext i16 @bswap_i16(i16 zeroext %a) nounwind {
; RV64I-LABEL: bswap_i16:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 8
; RV64I-NEXT:    slli a0, a0, 8
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    slli a0, a0, 48
; RV64I-NEXT:    srli a0, a0, 48
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_i16:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev8.h a0, a0
; RV64ZBP-NEXT:    ret
  %1 = tail call i16 @llvm.bswap.i16(i16 %a)
  ret i16 %1
}

declare i32 @llvm.bswap.i32(i32)

define signext i32 @bswap_i32(i32 signext %a) nounwind {
; RV64I-LABEL: bswap_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a1, a0, 8
; RV64I-NEXT:    lui a2, 16
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srliw a2, a0, 24
; RV64I-NEXT:    or a1, a1, a2
; RV64I-NEXT:    slli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    slliw a0, a0, 24
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 24
; RV64ZBP-NEXT:    ret
  %1 = tail call i32 @llvm.bswap.i32(i32 %a)
  ret i32 %1
}

; Similar to bswap_i32 but the result is not sign extended.
define void @bswap_i32_nosext(i32 signext %a, i32* %x) nounwind {
; RV64I-LABEL: bswap_i32_nosext:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a2, a0, 8
; RV64I-NEXT:    lui a3, 16
; RV64I-NEXT:    addiw a3, a3, -256
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    srliw a3, a0, 24
; RV64I-NEXT:    or a2, a2, a3
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    lui a4, 4080
; RV64I-NEXT:    and a3, a3, a4
; RV64I-NEXT:    slli a0, a0, 24
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    sw a0, 0(a1)
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_i32_nosext:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 24
; RV64ZBP-NEXT:    sw a0, 0(a1)
; RV64ZBP-NEXT:    ret
  %1 = tail call i32 @llvm.bswap.i32(i32 %a)
  store i32 %1, i32* %x
  ret void
}

declare i64 @llvm.bswap.i64(i64)

define i64 @bswap_i64(i64 %a) {
; RV64I-LABEL: bswap_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 24
; RV64I-NEXT:    lui a2, 4080
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 8
; RV64I-NEXT:    li a3, 255
; RV64I-NEXT:    slli a4, a3, 24
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a2, a0, 40
; RV64I-NEXT:    lui a4, 16
; RV64I-NEXT:    addiw a4, a4, -256
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    srli a4, a0, 56
; RV64I-NEXT:    or a2, a2, a4
; RV64I-NEXT:    or a1, a1, a2
; RV64I-NEXT:    slli a2, a0, 24
; RV64I-NEXT:    slli a4, a3, 40
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    srliw a4, a0, 24
; RV64I-NEXT:    slli a4, a4, 32
; RV64I-NEXT:    or a2, a2, a4
; RV64I-NEXT:    slli a4, a0, 40
; RV64I-NEXT:    slli a3, a3, 48
; RV64I-NEXT:    and a3, a4, a3
; RV64I-NEXT:    slli a0, a0, 56
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev8 a0, a0
; RV64ZBP-NEXT:    ret
  %1 = call i64 @llvm.bswap.i64(i64 %a)
  ret i64 %1
}

declare i8 @llvm.bitreverse.i8(i8)

define zeroext i8 @bitreverse_i8(i8 zeroext %a) nounwind {
; RV64I-LABEL: bitreverse_i8:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 4
; RV64I-NEXT:    andi a0, a0, 15
; RV64I-NEXT:    slli a0, a0, 4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    andi a1, a0, 51
; RV64I-NEXT:    slli a1, a1, 2
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    andi a0, a0, 51
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    andi a1, a0, 85
; RV64I-NEXT:    slli a1, a1, 1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    andi a0, a0, 85
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_i8:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.b a0, a0
; RV64ZBP-NEXT:    ret
  %1 = tail call i8 @llvm.bitreverse.i8(i8 %a)
  ret i8 %1
}

declare i16 @llvm.bitreverse.i16(i16)

define zeroext i16 @bitreverse_i16(i16 zeroext %a) nounwind {
; RV64I-LABEL: bitreverse_i16:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 8
; RV64I-NEXT:    slli a0, a0, 8
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    srli a1, a0, 4
; RV64I-NEXT:    lui a2, 1
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slli a0, a0, 4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 2
; RV64I-NEXT:    lui a2, 3
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slli a0, a0, 2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 1
; RV64I-NEXT:    lui a2, 5
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slli a0, a0, 1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_i16:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.h a0, a0
; RV64ZBP-NEXT:    ret
  %1 = tail call i16 @llvm.bitreverse.i16(i16 %a)
  ret i16 %1
}

declare i32 @llvm.bitreverse.i32(i32)

define signext i32 @bitreverse_i32(i32 signext %a) nounwind {
; RV64I-LABEL: bitreverse_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a1, a0, 8
; RV64I-NEXT:    lui a2, 16
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srliw a2, a0, 24
; RV64I-NEXT:    or a1, a1, a2
; RV64I-NEXT:    slli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    slliw a0, a0, 24
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    srli a1, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 31
; RV64ZBP-NEXT:    ret
  %1 = tail call i32 @llvm.bitreverse.i32(i32 %a)
  ret i32 %1
}

; Similar to bitreverse_i32 but the result is not sign extended.
define void @bitreverse_i32_nosext(i32 signext %a, i32* %x) nounwind {
; RV64I-LABEL: bitreverse_i32_nosext:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a2, a0, 8
; RV64I-NEXT:    lui a3, 16
; RV64I-NEXT:    addiw a3, a3, -256
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    srliw a3, a0, 24
; RV64I-NEXT:    or a2, a2, a3
; RV64I-NEXT:    slli a3, a0, 8
; RV64I-NEXT:    lui a4, 4080
; RV64I-NEXT:    and a3, a3, a4
; RV64I-NEXT:    slliw a0, a0, 24
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    lui a3, 61681
; RV64I-NEXT:    addiw a3, a3, -241
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    slliw a0, a0, 4
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    lui a3, 209715
; RV64I-NEXT:    addiw a3, a3, 819
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    slliw a0, a0, 2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    lui a3, 349525
; RV64I-NEXT:    addiw a3, a3, 1365
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    slli a0, a0, 1
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    sw a0, 0(a1)
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_i32_nosext:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 31
; RV64ZBP-NEXT:    sw a0, 0(a1)
; RV64ZBP-NEXT:    ret
  %1 = tail call i32 @llvm.bitreverse.i32(i32 %a)
  store i32 %1, i32* %x
  ret void
}

declare i64 @llvm.bitreverse.i64(i64)

define i64 @bitreverse_i64(i64 %a) nounwind {
; RV64I-LABEL: bitreverse_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 24
; RV64I-NEXT:    lui a2, 4080
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 8
; RV64I-NEXT:    li a3, 255
; RV64I-NEXT:    slli a4, a3, 24
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a2, a0, 40
; RV64I-NEXT:    lui a4, 16
; RV64I-NEXT:    addiw a4, a4, -256
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    srli a4, a0, 56
; RV64I-NEXT:    or a2, a2, a4
; RV64I-NEXT:    or a1, a1, a2
; RV64I-NEXT:    slli a2, a0, 24
; RV64I-NEXT:    slli a4, a3, 40
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    srliw a4, a0, 24
; RV64I-NEXT:    slli a4, a4, 32
; RV64I-NEXT:    or a2, a2, a4
; RV64I-NEXT:    slli a4, a0, 40
; RV64I-NEXT:    slli a3, a3, 48
; RV64I-NEXT:    and a3, a4, a3
; RV64I-NEXT:    slli a0, a0, 56
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    lui a3, %hi(.LCPI73_0)
; RV64I-NEXT:    ld a3, %lo(.LCPI73_0)(a3)
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    srli a1, a0, 4
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    lui a2, %hi(.LCPI73_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI73_1)(a2)
; RV64I-NEXT:    slli a0, a0, 4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 2
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    lui a2, %hi(.LCPI73_2)
; RV64I-NEXT:    ld a2, %lo(.LCPI73_2)(a2)
; RV64I-NEXT:    slli a0, a0, 2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 1
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slli a0, a0, 1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev a0, a0
; RV64ZBP-NEXT:    ret
  %1 = call i64 @llvm.bitreverse.i64(i64 %a)
  ret i64 %1
}

define i32 @bswap_rotr_i32(i32 %a) {
; RV64I-LABEL: bswap_rotr_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 8
; RV64I-NEXT:    lui a2, 4080
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    slli a2, a0, 24
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srliw a2, a0, 24
; RV64I-NEXT:    srliw a0, a0, 16
; RV64I-NEXT:    slli a0, a0, 8
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 16
; RV64I-NEXT:    srliw a1, a1, 16
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_rotr_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 8
; RV64ZBP-NEXT:    ret
  %1 = call i32 @llvm.bswap.i32(i32 %a)
  %2 = call i32 @llvm.fshr.i32(i32 %1, i32 %1, i32 16)
  ret i32 %2
}

define i32 @bswap_rotl_i32(i32 %a) {
; RV64I-LABEL: bswap_rotl_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a1, a0, 24
; RV64I-NEXT:    srliw a2, a0, 16
; RV64I-NEXT:    slli a2, a2, 8
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    slli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    slli a0, a0, 24
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    srliw a0, a0, 16
; RV64I-NEXT:    slliw a1, a1, 16
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_rotl_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    greviw a0, a0, 8
; RV64ZBP-NEXT:    ret
  %1 = call i32 @llvm.bswap.i32(i32 %a)
  %2 = call i32 @llvm.fshl.i32(i32 %1, i32 %1, i32 16)
  ret i32 %2
}

define i64 @bswap_rotr_i64(i64 %a) {
; RV64I-LABEL: bswap_rotr_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a1, a0, 24
; RV64I-NEXT:    li a2, 255
; RV64I-NEXT:    slli a3, a2, 40
; RV64I-NEXT:    and a1, a1, a3
; RV64I-NEXT:    srliw a3, a0, 24
; RV64I-NEXT:    slli a3, a3, 32
; RV64I-NEXT:    or a1, a1, a3
; RV64I-NEXT:    slli a3, a0, 40
; RV64I-NEXT:    slli a2, a2, 48
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    slli a3, a0, 56
; RV64I-NEXT:    or a2, a3, a2
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a2, a0, 40
; RV64I-NEXT:    lui a3, 16
; RV64I-NEXT:    addiw a3, a3, -256
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    srli a3, a0, 56
; RV64I-NEXT:    or a2, a2, a3
; RV64I-NEXT:    srli a3, a0, 24
; RV64I-NEXT:    lui a4, 4080
; RV64I-NEXT:    and a3, a3, a4
; RV64I-NEXT:    srli a0, a0, 32
; RV64I-NEXT:    slli a0, a0, 24
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    slli a0, a0, 32
; RV64I-NEXT:    srli a1, a1, 32
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_rotr_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev8.w a0, a0
; RV64ZBP-NEXT:    ret
  %1 = call i64 @llvm.bswap.i64(i64 %a)
  %2 = call i64 @llvm.fshr.i64(i64 %1, i64 %1, i64 32)
  ret i64 %2
}

define i64 @bswap_rotl_i64(i64 %a) {
; RV64I-LABEL: bswap_rotl_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 40
; RV64I-NEXT:    lui a2, 16
; RV64I-NEXT:    addiw a2, a2, -256
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 56
; RV64I-NEXT:    or a1, a1, a2
; RV64I-NEXT:    srli a2, a0, 24
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    srli a3, a0, 32
; RV64I-NEXT:    slli a3, a3, 24
; RV64I-NEXT:    or a2, a3, a2
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    slli a2, a0, 24
; RV64I-NEXT:    li a3, 255
; RV64I-NEXT:    slli a4, a3, 40
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    srliw a4, a0, 24
; RV64I-NEXT:    slli a4, a4, 32
; RV64I-NEXT:    or a2, a2, a4
; RV64I-NEXT:    slli a4, a0, 40
; RV64I-NEXT:    slli a3, a3, 48
; RV64I-NEXT:    and a3, a4, a3
; RV64I-NEXT:    slli a0, a0, 56
; RV64I-NEXT:    or a0, a0, a3
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    srli a0, a0, 32
; RV64I-NEXT:    slli a1, a1, 32
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bswap_rotl_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev8.w a0, a0
; RV64ZBP-NEXT:    ret
  %1 = call i64 @llvm.bswap.i64(i64 %a)
  %2 = call i64 @llvm.fshl.i64(i64 %1, i64 %1, i64 32)
  ret i64 %2
}

define i32 @bitreverse_bswap_i32(i32 %a) {
; RV64I-LABEL: bitreverse_bswap_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a1, a0, 4
; RV64I-NEXT:    lui a2, 61681
; RV64I-NEXT:    addiw a2, a2, -241
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 4
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 2
; RV64I-NEXT:    lui a2, 209715
; RV64I-NEXT:    addiw a2, a2, 819
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 1
; RV64I-NEXT:    lui a2, 349525
; RV64I-NEXT:    addiw a2, a2, 1365
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    slliw a0, a0, 1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_bswap_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.b a0, a0
; RV64ZBP-NEXT:    ret
  %1 = call i32 @llvm.bitreverse.i32(i32 %a)
  %2 = call i32 @llvm.bswap.i32(i32 %1)
  ret i32 %2
}

define i64 @bitreverse_bswap_i64(i64 %a) {
; RV64I-LABEL: bitreverse_bswap_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI79_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI79_0)(a1)
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    and a2, a2, a1
; RV64I-NEXT:    and a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI79_1)
; RV64I-NEXT:    ld a1, %lo(.LCPI79_1)(a1)
; RV64I-NEXT:    slli a0, a0, 4
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    srli a2, a0, 2
; RV64I-NEXT:    and a2, a2, a1
; RV64I-NEXT:    and a0, a0, a1
; RV64I-NEXT:    lui a1, %hi(.LCPI79_2)
; RV64I-NEXT:    ld a1, %lo(.LCPI79_2)(a1)
; RV64I-NEXT:    slli a0, a0, 2
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    srli a2, a0, 1
; RV64I-NEXT:    and a2, a2, a1
; RV64I-NEXT:    and a0, a0, a1
; RV64I-NEXT:    slli a0, a0, 1
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: bitreverse_bswap_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    rev.b a0, a0
; RV64ZBP-NEXT:    ret
  %1 = call i64 @llvm.bitreverse.i64(i64 %a)
  %2 = call i64 @llvm.bswap.i64(i64 %1)
  ret i64 %2
}

define signext i32 @shfl1_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: shfl1_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, 629146
; RV64I-NEXT:    addiw a1, a1, -1639
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    slli a2, a0, 1
; RV64I-NEXT:    lui a3, 279620
; RV64I-NEXT:    addiw a3, a3, 1092
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    lui a2, 139810
; RV64I-NEXT:    addiw a2, a2, 546
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl1_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip.n a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i32 %a, -1717986919
  %shl = shl i32 %a, 1
  %and1 = and i32 %shl, 1145324612
  %or = or i32 %and1, %and
  %shr = lshr i32 %a, 1
  %and2 = and i32 %shr, 572662306
  %or3 = or i32 %or, %and2
  ret i32 %or3
}

define i64 @shfl1_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: shfl1_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI81_1)
; RV64I-NEXT:    ld a1, %lo(.LCPI81_1)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI81_0)
; RV64I-NEXT:    ld a2, %lo(.LCPI81_0)(a2)
; RV64I-NEXT:    slli a3, a0, 1
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    lui a3, %hi(.LCPI81_2)
; RV64I-NEXT:    ld a3, %lo(.LCPI81_2)(a3)
; RV64I-NEXT:    and a2, a0, a2
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl1_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip.n a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i64 %a, -7378697629483820647
  %shl = shl i64 %a, 1
  %and1 = and i64 %shl, 4919131752989213764
  %or = or i64 %and, %and1
  %shr = lshr i64 %a, 1
  %and2 = and i64 %shr, 2459565876494606882
  %or3 = or i64 %or, %and2
  ret i64 %or3
}

define signext i32 @shfl2_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: shfl2_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, 801852
; RV64I-NEXT:    addiw a1, a1, 963
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    slli a2, a0, 2
; RV64I-NEXT:    lui a3, 197379
; RV64I-NEXT:    addiw a3, a3, 48
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    lui a2, 49345
; RV64I-NEXT:    addiw a2, a2, -1012
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl2_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip2.b a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i32 %a, -1010580541
  %shl = shl i32 %a, 2
  %and1 = and i32 %shl, 808464432
  %or = or i32 %and1, %and
  %shr = lshr i32 %a, 2
  %and2 = and i32 %shr, 202116108
  %or3 = or i32 %and2, %or
  ret i32 %or3
}

define i64 @shfl2_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: shfl2_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI83_1)
; RV64I-NEXT:    ld a1, %lo(.LCPI83_1)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI83_0)
; RV64I-NEXT:    ld a2, %lo(.LCPI83_0)(a2)
; RV64I-NEXT:    slli a3, a0, 2
; RV64I-NEXT:    and a1, a3, a1
; RV64I-NEXT:    lui a3, %hi(.LCPI83_2)
; RV64I-NEXT:    ld a3, %lo(.LCPI83_2)(a3)
; RV64I-NEXT:    and a2, a0, a2
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl2_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip2.b a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i64 %a, -4340410370284600381
  %shl = shl i64 %a, 2
  %and1 = and i64 %shl, 3472328296227680304
  %or = or i64 %and, %and1
  %shr = lshr i64 %a, 2
  %and2 = and i64 %shr, 868082074056920076
  %or3 = or i64 %and2, %or
  ret i64 %or3
}

define signext i32 @shfl4_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: shfl4_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, 983295
; RV64I-NEXT:    addiw a1, a1, 15
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    slli a2, a0, 4
; RV64I-NEXT:    lui a3, 61441
; RV64I-NEXT:    addiw a3, a3, -256
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    lui a3, 3840
; RV64I-NEXT:    addiw a3, a3, 240
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl4_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip4.h a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i32 %a, -267390961
  %shl = shl i32 %a, 4
  %and1 = and i32 %shl, 251662080
  %shr = lshr i32 %a, 4
  %and2 = and i32 %shr, 15728880
  %or = or i32 %and2, %and
  %or3 = or i32 %or, %and1
  ret i32 %or3
}

define i64 @shfl4_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: shfl4_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, %hi(.LCPI85_0)
; RV64I-NEXT:    ld a1, %lo(.LCPI85_0)(a1)
; RV64I-NEXT:    lui a2, %hi(.LCPI85_1)
; RV64I-NEXT:    ld a2, %lo(.LCPI85_1)(a2)
; RV64I-NEXT:    slli a3, a0, 4
; RV64I-NEXT:    lui a4, %hi(.LCPI85_2)
; RV64I-NEXT:    ld a4, %lo(.LCPI85_2)(a4)
; RV64I-NEXT:    and a2, a3, a2
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    srli a0, a0, 4
; RV64I-NEXT:    and a0, a0, a4
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl4_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip4.h a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i64 %a, -1148435428713435121
  %shl = shl i64 %a, 4
  %and1 = and i64 %shl, 1080880403494997760
  %shr = lshr i64 %a, 4
  %and2 = and i64 %shr, 67555025218437360
  %or = or i64 %and1, %and2
  %or3 = or i64 %or, %and
  ret i64 %or3
}

define signext i32 @shfl8_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: shfl8_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, 1044480
; RV64I-NEXT:    addiw a1, a1, 255
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    slli a2, a0, 8
; RV64I-NEXT:    lui a3, 4080
; RV64I-NEXT:    and a2, a2, a3
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    lui a3, 16
; RV64I-NEXT:    addiw a3, a3, -256
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    or a0, a0, a2
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl8_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip8.w a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i32 %a, -16776961
  %shl = shl i32 %a, 8
  %and1 = and i32 %shl, 16711680
  %shr = lshr i32 %a, 8
  %and2 = and i32 %shr, 65280
  %or = or i32 %and, %and2
  %or3 = or i32 %or, %and1
  ret i32 %or3
}

define i64 @shfl8_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: shfl8_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lui a1, 983041
; RV64I-NEXT:    slli a1, a1, 4
; RV64I-NEXT:    addi a1, a1, -1
; RV64I-NEXT:    slli a1, a1, 24
; RV64I-NEXT:    addi a1, a1, 255
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    slli a2, a0, 8
; RV64I-NEXT:    li a3, 255
; RV64I-NEXT:    slli a3, a3, 32
; RV64I-NEXT:    addi a3, a3, 255
; RV64I-NEXT:    slli a4, a3, 16
; RV64I-NEXT:    and a2, a2, a4
; RV64I-NEXT:    srli a0, a0, 8
; RV64I-NEXT:    slli a3, a3, 8
; RV64I-NEXT:    and a0, a0, a3
; RV64I-NEXT:    or a0, a0, a1
; RV64I-NEXT:    or a0, a2, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl8_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip8.w a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i64 %a, -72056494543077121
  %shl = shl i64 %a, 8
  %and1 = and i64 %shl, 71776119077928960
  %shr = lshr i64 %a, 8
  %and2 = and i64 %shr, 280375465148160
  %or = or i64 %and2, %and
  %or3 = or i64 %and1, %or
  ret i64 %or3
}

define i64 @shfl16(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: shfl16:
; RV64I:       # %bb.0:
; RV64I-NEXT:    li a1, -1
; RV64I-NEXT:    slli a1, a1, 32
; RV64I-NEXT:    addi a1, a1, 1
; RV64I-NEXT:    slli a1, a1, 16
; RV64I-NEXT:    addi a1, a1, -1
; RV64I-NEXT:    and a1, a0, a1
; RV64I-NEXT:    srliw a2, a0, 16
; RV64I-NEXT:    slli a2, a2, 32
; RV64I-NEXT:    or a1, a2, a1
; RV64I-NEXT:    srli a0, a0, 16
; RV64I-NEXT:    lui a2, 65535
; RV64I-NEXT:    slli a2, a2, 4
; RV64I-NEXT:    and a0, a0, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: shfl16:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zip16 a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i64 %a, -281474976645121
  %shl = shl i64 %a, 16
  %and1 = and i64 %shl, 281470681743360
  %or = or i64 %and1, %and
  %shr = lshr i64 %a, 16
  %and2 = and i64 %shr, 4294901760
  %or3 = or i64 %or, %and2
  ret i64 %or3
}

define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind {
; RV64I-LABEL: packu_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srliw a0, a0, 16
; RV64I-NEXT:    lui a2, 1048560
; RV64I-NEXT:    and a1, a1, a2
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: packu_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    packuw a0, a0, a1
; RV64ZBP-NEXT:    ret
  %shr = lshr i32 %a, 16
  %shr1 = and i32 %b, -65536
  %or = or i32 %shr1, %shr
  ret i32 %or
}

define i64 @packu_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: packu_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    srli a0, a0, 32
; RV64I-NEXT:    srli a1, a1, 32
; RV64I-NEXT:    slli a1, a1, 32
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: packu_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    packu a0, a0, a1
; RV64ZBP-NEXT:    ret
  %shr = lshr i64 %a, 32
  %shr1 = and i64 %b, -4294967296
  %or = or i64 %shr1, %shr
  ret i64 %or
}

define i32 @zexth_i32(i32 %a) nounwind {
; RV64I-LABEL: zexth_i32:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a0, a0, 48
; RV64I-NEXT:    srli a0, a0, 48
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: zexth_i32:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zext.h a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i32 %a, 65535
  ret i32 %and
}

define i64 @zexth_i64(i64 %a) nounwind {
; RV64I-LABEL: zexth_i64:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a0, a0, 48
; RV64I-NEXT:    srli a0, a0, 48
; RV64I-NEXT:    ret
;
; RV64ZBP-LABEL: zexth_i64:
; RV64ZBP:       # %bb.0:
; RV64ZBP-NEXT:    zext.h a0, a0
; RV64ZBP-NEXT:    ret
  %and = and i64 %a, 65535
  ret i64 %and
}