[llvm] [RISCV] Implement Intrinsics and CodeGen Support for XCValu Extension… (PR #78138)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 00:21:56 PST 2024


================
@@ -0,0 +1,585 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -mtriple=riscv32 -mattr=+m -mattr=+xcvalu -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s
+
+declare i32 @llvm.abs.i32(i32, i1)
+declare i32 @llvm.smin.i32(i32, i32)
+declare i32 @llvm.smax.i32(i32, i32)
+declare i32 @llvm.umin.i32(i32, i32)
+declare i32 @llvm.umax.i32(i32, i32)
+
+define i32 @abs(i32 %a) {
+; CHECK-LABEL: abs:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.abs a0, a0
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.abs.i32(i32 %a, i1 false)
+  ret i32 %1
+}
+
+define i1 @slet(i32 %a, i32 %b) {
+; CHECK-LABEL: slet:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.slet a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = icmp sle i32 %a, %b
+  ret i1 %1
+}
+
+define i1 @sletu(i32 %a, i32 %b) {
+; CHECK-LABEL: sletu:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.sletu a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = icmp ule i32 %a, %b
+  ret i1 %1
+}
+
+define i32 @smin(i32 %a, i32 %b) {
+; CHECK-LABEL: smin:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.min a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.smin.i32(i32 %a, i32 %b)
+  ret i32 %1
+}
+
+define i32 @umin(i32 %a, i32 %b) {
+; CHECK-LABEL: umin:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.minu a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.umin.i32(i32 %a, i32 %b)
+  ret i32 %1
+}
+
+define i32 @smax(i32 %a, i32 %b) {
+; CHECK-LABEL: smax:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.max a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.smax.i32(i32 %a, i32 %b)
+  ret i32 %1
+}
+
+define i32 @umax(i32 %a, i32 %b) {
+; CHECK-LABEL: umax:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.maxu a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.umax.i32(i32 %a, i32 %b)
+  ret i32 %1
+}
+
+define i32 @exths(i16 %a) {
+; CHECK-LABEL: exths:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    # kill: def $x11 killed $x10
+; CHECK-NEXT:    cv.exths a0, a0
+; CHECK-NEXT:    ret
+  %1 = sext i16 %a to i32
+  ret i32 %1
+}
+
+define i32 @exthz(i16 %a) {
+; CHECK-LABEL: exthz:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    # kill: def $x11 killed $x10
+; CHECK-NEXT:    cv.exthz a0, a0
+; CHECK-NEXT:    ret
+  %1 = zext i16 %a to i32
+  ret i32 %1
+}
+
+define i32 @extbs(i8 %a) {
+; CHECK-LABEL: extbs:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    # kill: def $x11 killed $x10
+; CHECK-NEXT:    cv.extbs a0, a0
+; CHECK-NEXT:    ret
+  %1 = sext i8 %a to i32
+  ret i32 %1
+}
+
+define i32 @extbz(i8 %a) {
+; CHECK-LABEL: extbz:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    # kill: def $x11 killed $x10
+; CHECK-NEXT:    cv.extbz a0, a0
+; CHECK-NEXT:    ret
+  %1 = zext i8 %a to i32
+  ret i32 %1
+}
+
+define i32 @clip(i32 %a) {
+; CHECK-LABEL: clip:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.clip a0, a0, 7
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.smax.i32(i32 %a, i32 -64)
+  %2 = call i32 @llvm.smin.i32(i32 %1, i32 63)
+  ret i32 %2
+}
+
+define i32 @clipr(i32 %a, i32 %b) {
+; CHECK-LABEL: clipr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.abs a0, a1
+; CHECK-NEXT:    cv.clipr a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.abs.i32(i32 %b, i1 false)
+  %2 = xor i32 %1, -1
+  %3 = call i32 @llvm.smax.i32(i32 %1, i32 %2)
+  %4 = call i32 @llvm.smin.i32(i32 %3, i32 %1)
+  ret i32 %4
+}
+
+define i32 @clipu(i32 %a) {
+; CHECK-LABEL: clipu:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.clipu a0, a0, 5
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.smax.i32(i32 %a, i32 0)
+  %2 = call i32 @llvm.smin.i32(i32 %1, i32 15)
+  ret i32 %2
+}
+
+define i32 @clipur(i32 %a, i32 %b) {
+; CHECK-LABEL: clipur:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.clipur a0, a0, a1
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.smax.i32(i32 %a, i32 0)
+  %2 = call i32 @llvm.smin.i32(i32 %1, i32 %b)
+  ret i32 %2
+}
+
+define i32 @addN(i32 %a, i32 %b) {
+; CHECK-LABEL: addN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addn a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = ashr i32 %1, 5
+  ret i32 %2
+}
+
+define i32 @adduN(i32 %a, i32 %b) {
+; CHECK-LABEL: adduN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addun a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = lshr i32 %1, 5
+  ret i32 %2
+}
+
+define i32 @addRN(i32 %a, i32 %b) {
+; CHECK-LABEL: addRN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addrn a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = add i32 %1, 16
+  %3 = ashr i32 %2, 5
+  ret i32 %3
+}
+
+define i32 @adduRN(i32 %a, i32 %b) {
+; CHECK-LABEL: adduRN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addurn a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = add i32 %1, 16
+  %3 = lshr i32 %2, 5
+  ret i32 %3
+}
+
+define i32 @addNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: addNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addnr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = ashr i32 %1, %c
+  ret i32 %2
+}
+
+define i32 @adduNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: adduNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addunr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = lshr i32 %1, %c
+  ret i32 %2
+}
+
+define i32 @addRNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: addRNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addrnr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = shl i32 1, %c
+  %3 = lshr i32 %2, 1
+  %4 = add i32 %1, %3
+  %5 = ashr i32 %4, %c
+  ret i32 %5
+}
+
+define i32 @adduRNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: adduRNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.addurnr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = add i32 %a, %b
+  %2 = shl i32 1, %c
+  %3 = lshr i32 %2, 1
+  %4 = add i32 %1, %3
+  %5 = lshr i32 %4, %c
+  ret i32 %5
+}
+
+define i32 @subN(i32 %a, i32 %b) {
+; CHECK-LABEL: subN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.subn a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = ashr i32 %1, 5
+  ret i32 %2
+}
+
+define i32 @subuN(i32 %a, i32 %b) {
+; CHECK-LABEL: subuN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.subun a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = lshr i32 %1, 5
+  ret i32 %2
+}
+
+define i32 @subRN(i32 %a, i32 %b) {
+; CHECK-LABEL: subRN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.subrn a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = add i32 %1, 16
+  %3 = ashr i32 %2, 5
+  ret i32 %3
+}
+
+define i32 @subuRN(i32 %a, i32 %b) {
+; CHECK-LABEL: subuRN:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.suburn a0, a0, a1, 5
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = add i32 %1, 16
+  %3 = lshr i32 %2, 5
+  ret i32 %3
+}
+
+define i32 @subNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: subNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.subnr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = ashr i32 %1, %c
+  ret i32 %2
+}
+
+define i32 @subuNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: subuNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.subunr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = lshr i32 %1, %c
+  ret i32 %2
+}
+
+define i32 @subRNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: subRNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.subrnr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = shl i32 1, %c
+  %3 = lshr i32 %2, 1
+  %4 = add i32 %1, %3
+  %5 = ashr i32 %4, %c
+  ret i32 %5
+}
+
+define i32 @subuRNr(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: subuRNr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.suburnr a0, a1, a2
+; CHECK-NEXT:    ret
+  %1 = sub i32 %a, %b
+  %2 = shl i32 1, %c
+  %3 = lshr i32 %2, 1
+  %4 = add i32 %1, %3
+  %5 = lshr i32 %4, %c
+  ret i32 %5
+}
+
+declare i32 @llvm.riscv.cv.alu.exths(i32)
+
+define i32 @test.cv.alu.exths(i32 %a) {
+; CHECK-LABEL: test.cv.alu.exths:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.exths a0, a0
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.riscv.cv.alu.exths(i32 %a)
+  ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.exthz(i32)
+
+define i32 @test.cv.alu.exthz(i32 %a) {
+; CHECK-LABEL: test.cv.alu.exthz:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cv.exthz a0, a0
+; CHECK-NEXT:    ret
+  %1 = call i32 @llvm.riscv.cv.alu.exthz(i32 %a)
----------------
topperc wrote:

Why do we need an intrinsic for exthz? Isn't this just AND with 0xffff?

https://github.com/llvm/llvm-project/pull/78138


More information about the llvm-commits mailing list