| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbp -verify-machineinstrs < %s \ |
| ; RUN: | FileCheck %s -check-prefix=RV64ZBP |
| |
| declare i32 @llvm.riscv.grev.i32(i32 %a, i32 %b) |
| |
| define signext i32 @grev32(i32 signext %a, i32 signext %b) nounwind { |
| ; RV64ZBP-LABEL: grev32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: grevw a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.grev.i32(i32 %a, i32 %b) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @grev32_demandedbits(i32 signext %a, i32 signext %b, i32 signext %c) nounwind { |
| ; RV64ZBP-LABEL: grev32_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: add a0, a0, a1 |
| ; RV64ZBP-NEXT: grevw a0, a0, a2 |
| ; RV64ZBP-NEXT: ret |
| %d = add i32 %a, %b |
| %e = and i32 %c, 31 |
| %tmp = call i32 @llvm.riscv.grev.i32(i32 %d, i32 %e) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @grevi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: grevi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: greviw a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.grev.i32(i32 %a, i32 13) |
| ret i32 %tmp |
| } |
| |
| define zeroext i32 @grevi32_zext(i32 zeroext %a) nounwind { |
| ; RV64ZBP-LABEL: grevi32_zext: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: grevi a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.grev.i32(i32 %a, i32 13) |
| ret i32 %tmp |
| } |
| |
| declare i32 @llvm.riscv.gorc.i32(i32 %a, i32 %b) |
| |
| define signext i32 @gorc32(i32 signext %a, i32 signext %b) nounwind { |
| ; RV64ZBP-LABEL: gorc32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: gorcw a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.gorc.i32(i32 %a, i32 %b) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @gorc32_demandedbits(i32 signext %a, i32 signext %b, i32 signext %c) nounwind { |
| ; RV64ZBP-LABEL: gorc32_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: add a0, a0, a1 |
| ; RV64ZBP-NEXT: gorcw a0, a0, a2 |
| ; RV64ZBP-NEXT: ret |
| %d = add i32 %a, %b |
| %e = and i32 %c, 31 |
| %tmp = call i32 @llvm.riscv.gorc.i32(i32 %d, i32 %e) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @gorci32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: gorci32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: gorciw a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.gorc.i32(i32 %a, i32 13) |
| ret i32 %tmp |
| } |
| |
| define zeroext i32 @gorci32_zext(i32 zeroext %a) nounwind { |
| ; RV64ZBP-LABEL: gorci32_zext: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.gorc.i32(i32 %a, i32 31) |
| ret i32 %tmp |
| } |
| |
| declare i32 @llvm.riscv.shfl.i32(i32 %a, i32 %b) |
| |
| define signext i32 @shfl32(i32 signext %a, i32 signext %b) nounwind { |
| ; RV64ZBP-LABEL: shfl32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: shflw a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 %b) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @shfl32_demandedbits(i32 signext %a, i32 signext %b, i32 signext %c) nounwind { |
| ; RV64ZBP-LABEL: shfl32_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: add a0, a0, a1 |
| ; RV64ZBP-NEXT: shflw a0, a0, a2 |
| ; RV64ZBP-NEXT: ret |
| %d = add i32 %a, %b |
| %e = and i32 %c, 15 |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %d, i32 %e) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zipni32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zipni32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.n a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 1) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zip2bi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zip2bi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 2) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zipbi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zipbi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 3) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zip4hi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zip4hi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip4.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 4) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zip2hi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zip2hi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 6) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @ziphi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: ziphi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 7) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @shfli32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: shfli32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: shfli a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 13) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zip4wi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zip4wi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip4.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 12) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zip2wi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zip2wi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 14) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zipwi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zipwi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 15) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @zip8wi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: zip8wi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip8.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 8) |
| ret i32 %tmp |
| } |
| |
| declare i32 @llvm.riscv.unshfl.i32(i32 %a, i32 %b) |
| |
| define signext i32 @unshfl32(i32 signext %a, i32 signext %b) nounwind { |
| ; RV64ZBP-LABEL: unshfl32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unshflw a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 %b) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unshfl32_demandedbits(i32 signext %a, i32 signext %b, i32 signext %c) nounwind { |
| ; RV64ZBP-LABEL: unshfl32_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: add a0, a0, a1 |
| ; RV64ZBP-NEXT: unshflw a0, a0, a2 |
| ; RV64ZBP-NEXT: ret |
| %d = add i32 %a, %b |
| %e = and i32 %c, 15 |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %d, i32 %e) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzipni32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzipni32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.n a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 1) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzip2bi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2bi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 2) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzipbi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzipbi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 3) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzip4hi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzip4hi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip4.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 4) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzip2hi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2hi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 6) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unziphi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unziphi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 7) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unshfli32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unshfli32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unshfli a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 13) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzip4wi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzip4wi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip4.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 12) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzip2wi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2wi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 14) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzipwi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzipwi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 15) |
| ret i32 %tmp |
| } |
| |
| define signext i32 @unzip8wi32(i32 signext %a) nounwind { |
| ; RV64ZBP-LABEL: unzip8wi32: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip8.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 8) |
| ret i32 %tmp |
| } |
| |
| declare i64 @llvm.riscv.grev.i64(i64 %a, i64 %b) |
| |
| define i64 @grev64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: grev64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: grev a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| define i64 @grev64_demandedbits(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: grev64_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: grev a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %c = and i64 %b, 63 |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 %c) |
| ret i64 %tmp |
| } |
| |
| define i64 @grevi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: grevi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: grevi a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 13) |
| ret i64 %tmp |
| } |
| |
| ; Make sure we don't fold this rotate with the grev. We can only fold a rotate |
| ; by 32. |
| define i64 @grevi64_24_rotl_16(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: grevi64_24_rotl_16: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev8.w a0, a0 |
| ; RV64ZBP-NEXT: rori a0, a0, 48 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 24) |
| %tmp1 = call i64 @llvm.fshl.i64(i64 %tmp, i64 %tmp, i64 16) |
| ret i64 %tmp1 |
| } |
| declare i64 @llvm.fshl.i64(i64, i64, i64) |
| |
| ; Make sure we don't fold this rotate with the grev. We can only fold a rotate |
| ; by 32. |
| define i64 @grevi64_24_rotr_16(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: grevi64_24_rotr_16: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev8.w a0, a0 |
| ; RV64ZBP-NEXT: rori a0, a0, 16 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 24) |
| %tmp1 = call i64 @llvm.fshr.i64(i64 %tmp, i64 %tmp, i64 16) |
| ret i64 %tmp1 |
| } |
| declare i64 @llvm.fshr.i64(i64, i64, i64) |
| |
| define i64 @revhwi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: revhwi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 15) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev16wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev16wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev16.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 16) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev8wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev8wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev8.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 24) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev4wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev4wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev4.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 28) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev2wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev2wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev2.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 30) |
| ret i64 %tmp |
| } |
| |
| define i64 @revwi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: revwi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 31) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev32i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev32i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev32 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 32) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev16i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev16i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev16 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 48) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev8i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev8i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev8 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 56) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev4i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev4i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev4 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 60) |
| ret i64 %tmp |
| } |
| |
| define i64 @rev2i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: rev2i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev2 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 62) |
| ret i64 %tmp |
| } |
| |
| define i64 @revi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: revi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: rev a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.grev.i64(i64 %a, i64 63) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.gorc.i64(i64 %a, i64 %b) |
| |
| define i64 @gorc64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: gorc64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: gorc a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| define i64 @gorc64_demandedbits(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: gorc64_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: gorc a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %c = and i64 %b, 63 |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 %c) |
| ret i64 %tmp |
| } |
| |
| define i64 @gorci64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: gorci64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: gorci a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 13) |
| ret i64 %tmp |
| } |
| |
| ; The second OR is redundant with the first. Make sure we remove it. |
| define i64 @gorci64_knownbits(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: gorci64_knownbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: lui a1, %hi(.LCPI54_0) |
| ; RV64ZBP-NEXT: ld a1, %lo(.LCPI54_0)(a1) |
| ; RV64ZBP-NEXT: or a0, a0, a1 |
| ; RV64ZBP-NEXT: orc32 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = or i64 %a, 72624976668147840 ; 0x102040810204080 |
| %tmp2 = call i64 @llvm.riscv.gorc.i64(i64 %tmp, i64 32) |
| %tmp3 = or i64 %tmp2, 1234624599046636680 ; 0x1122448811224488 |
| ret i64 %tmp3 |
| } |
| |
| define i64 @orchi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orchi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 15) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc16wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc16wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc16.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 16) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc8wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc8wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc8.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 24) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc4wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc4wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc4.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 28) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc2wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc2wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc2.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 30) |
| ret i64 %tmp |
| } |
| |
| define i64 @orcwi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orcwi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 31) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc32i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc32i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc32 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 32) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc16i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc16i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc16 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 48) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc8i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc8i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc8 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 56) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc4i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc4i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc4 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 60) |
| ret i64 %tmp |
| } |
| |
| define i64 @orc2i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orc2i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc2 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 62) |
| ret i64 %tmp |
| } |
| |
| define i64 @orci64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: orci64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: orc a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.gorc.i64(i64 %a, i64 63) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.shfl.i64(i64 %a, i64 %b) |
| |
| define i64 @shfl64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: shfl64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: shfl a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| define i64 @shfl64_demandedbits(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: shfl64_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: shfl a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %c = and i64 %b, 31 |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 %c) |
| ret i64 %tmp |
| } |
| |
| define i64 @shfli64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: shfli64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: shfli a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 13) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip4wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip4wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip4.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 12) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip2wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip2wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 14) |
| ret i64 %tmp |
| } |
| |
| define i64 @zipwi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zipwi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 15) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip8i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip8i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip8 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 24) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip4i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip4i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip4 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 28) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip2i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip2i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 30) |
| ret i64 %tmp |
| } |
| |
| define i64 @zipi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zipi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 31) |
| ret i64 %tmp |
| } |
| |
| define i64 @zipni64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zipni64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.n a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 1) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip2bi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip2bi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 2) |
| ret i64 %tmp |
| } |
| |
| define i64 @zipbi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zipbi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 3) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip4hi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip4hi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip4.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 4) |
| ret i64 %tmp |
| } |
| |
| define i64 @zip2hi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: zip2hi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip2.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 6) |
| ret i64 %tmp |
| } |
| |
| define i64 @ziphi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: ziphi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: zip.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.shfl.i64(i64 %a, i64 7) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.unshfl.i64(i64 %a, i64 %b) |
| |
| define i64 @unshfl64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: unshfl64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unshfl a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| define i64 @unshfl64_demandedbits(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: unshfl64_demandedbits: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unshfl a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %c = and i64 %b, 31 |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 %c) |
| ret i64 %tmp |
| } |
| |
| define i64 @unshfli64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unshfli64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unshfli a0, a0, 13 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 13) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip4wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip4wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip4.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 12) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip2wi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2wi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 14) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzipwi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzipwi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.w a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 15) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip8i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip8i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip8 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 24) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip4i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip4i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip4 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 28) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip2i64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2i64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2 a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 30) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzipi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzipi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 31) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzipni64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzipni64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.n a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 1) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip2bi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2bi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 2) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzipbi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzipbi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.b a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 3) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip4hi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip4hi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip4.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 4) |
| ret i64 %tmp |
| } |
| |
| define i64 @unzip2hi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unzip2hi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip2.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 6) |
| ret i64 %tmp |
| } |
| |
| define i64 @unziphi64(i64 %a) nounwind { |
| ; RV64ZBP-LABEL: unziphi64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: unzip.h a0, a0 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.unshfl.i64(i64 %a, i64 7) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.xperm.n.i64(i64 %a, i64 %b) |
| |
| define i64 @xpermn64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: xpermn64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: xperm.n a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.xperm.n.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.xperm.b.i64(i64 %a, i64 %b) |
| |
| define i64 @xpermb64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: xpermb64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: xperm.b a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.xperm.b.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.xperm.h.i64(i64 %a, i64 %b) |
| |
| define i64 @xpermh64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: xpermh64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: xperm.h a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.xperm.h.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |
| |
| declare i64 @llvm.riscv.xperm.w.i64(i64 %a, i64 %b) |
| |
| define i64 @xpermw64(i64 %a, i64 %b) nounwind { |
| ; RV64ZBP-LABEL: xpermw64: |
| ; RV64ZBP: # %bb.0: |
| ; RV64ZBP-NEXT: xperm.w a0, a0, a1 |
| ; RV64ZBP-NEXT: ret |
| %tmp = call i64 @llvm.riscv.xperm.w.i64(i64 %a, i64 %b) |
| ret i64 %tmp |
| } |