sunshaoce created this revision.
sunshaoce added reviewers: asb, craig.topper, jrtc27, Jim, luismarques,
kito-cheng, frasercrmck.
Herald added subscribers: VincentWu, luke957, StephenFan, vkmr, evandro,
apazos, sameer.abuasal, s.egerton, benna, psnobl, jocewei, PkmX, the_o,
brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, shiva0217, niosHD,
sabuasal, simoncook, johnrusso, rbar, hiraditya, arichardson.
Herald added a project: All.
sunshaoce requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, pcwang-thead, eopXD,
MaskRay.
Herald added projects: clang, LLVM.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D128604
Files:
clang/include/clang/Basic/BuiltinsRISCV.def
clang/test/CodeGen/RISCV/rvp-intrinsics/riscv32-zbpbo.c
clang/test/CodeGen/RISCV/rvp-intrinsics/riscv64-zbpbo.c
llvm/lib/Support/RISCVISAInfo.cpp
llvm/lib/Target/RISCV/RISCV.td
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
llvm/lib/Target/RISCV/RISCVSubtarget.h
llvm/test/CodeGen/RISCV/rv32zbpbo.ll
llvm/test/CodeGen/RISCV/rv64zbpbo.ll
llvm/test/MC/RISCV/rv32zbpbo-valid.s
llvm/test/MC/RISCV/rv64zbpbo-valid.s
Index: llvm/test/MC/RISCV/rv64zbpbo-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zbpbo-valid.s
@@ -0,0 +1,35 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbpbo -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbpbo < %s \
+# RUN: | llvm-objdump --mattr=+experimental-zbpbo -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: pack t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
+pack t0, t1, t2
+
+# CHECK-ASM-AND-OBJ: packu t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48]
+packu t0, t1, t2
+
+# CHECK-ASM-AND-OBJ: fsrw t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xbb,0x52,0xc3,0x3d]
+fsrw t0, t1, t2, t3
+
+# CHECK-ASM-AND-OBJ: max t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x62,0x73,0x0a]
+max t0, t1, t2
+
+# CHECK-ASM-AND-OBJ: min t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x0a]
+min t0, t1, t2
+
+# CHECK-S-OBJ: rev8.h t0, t1
+rev8.h x5, x6
+
+# CHECK-ASM-AND-OBJ: cmix t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0x92,0x63,0xe6]
+cmix t0, t1, t2, t3
+
+# CHECK-ASM: encoding: [0x93,0x52,0xf3,0x6b]
+rev t0, t1
Index: llvm/test/MC/RISCV/rv32zbpbo-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zbpbo-valid.s
@@ -0,0 +1,43 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbpbo -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbpbo < %s \
+# RUN: | llvm-objdump --mattr=+experimental-zbpbo -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: clz t0, t1
+# CHECK-ASM: encoding: [0x93,0x12,0x03,0x60]
+clz t0, t1
+
+# CHECK-ASM-AND-OBJ: pack t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
+pack t0, t1, t2
+
+# CHECK-ASM-AND-OBJ: packu t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48]
+packu t0, t1, t2
+
+# CHECK-ASM-AND-OBJ: fsr t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0x52,0xc3,0x3d]
+fsr t0, t1, t2, t3
+
+# CHECK-ASM-AND-OBJ: fsri t0, t1, t2, 0
+# CHECK-ASM: encoding: [0x93,0x52,0x03,0x3c]
+fsri t0, t1, t2, 0
+
+# CHECK-ASM-AND-OBJ: max t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x62,0x73,0x0a]
+max t0, t1, t2
+
+# CHECK-ASM-AND-OBJ: min t0, t1, t2
+# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x0a]
+min t0, t1, t2
+
+# CHECK-S-OBJ: rev8.h t0, t1
+rev8.h x5, x6
+
+# CHECK-ASM-AND-OBJ: cmix t0, t1, t2, t3
+# CHECK-ASM: encoding: [0xb3,0x92,0x63,0xe6]
+cmix t0, t1, t2, t3
+
+# CHECK-ASM: encoding: [0x93,0x52,0xf3,0x69]
+rev t0, t1
Index: llvm/test/CodeGen/RISCV/rv64zbpbo.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/rv64zbpbo.ll
@@ -0,0 +1,103 @@
+; 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-zbpbo -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64ZBPBO
+
+define i64 @pack_i64(i64 %a, i64 %b) nounwind {
+; RV64I-LABEL: pack_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 32
+; RV64I-NEXT: srli a0, a0, 32
+; RV64I-NEXT: slli a1, a1, 32
+; RV64I-NEXT: or a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBPBO-LABEL: pack_i64:
+; RV64ZBPBO: # %bb.0:
+; RV64ZBPBO-NEXT: pack a0, a0, a1
+; RV64ZBPBO-NEXT: ret
+ %shl = and i64 %a, 4294967295
+ %shl1 = shl i64 %b, 32
+ %or = or i64 %shl1, %shl
+ ret i64 %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
+;
+; RV64ZBPBO-LABEL: packu_i64:
+; RV64ZBPBO: # %bb.0:
+; RV64ZBPBO-NEXT: packu a0, a0, a1
+; RV64ZBPBO-NEXT: ret
+ %shr = lshr i64 %a, 32
+ %shr1 = and i64 %b, -4294967296
+ %or = or i64 %shr1, %shr
+ ret i64 %or
+}
+
+; TODO: fsrw
+
+define i64 @max_i64(i64 %a, i64 %b) nounwind {
+; RV64I-LABEL: max_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: blt a1, a0, .LBB2_2
+; RV64I-NEXT: # %bb.1:
+; RV64I-NEXT: mv a0, a1
+; RV64I-NEXT: .LBB2_2:
+; RV64I-NEXT: ret
+;
+; RV64ZBPBO-LABEL: max_i64:
+; RV64ZBPBO: # %bb.0:
+; RV64ZBPBO-NEXT: max a0, a0, a1
+; RV64ZBPBO-NEXT: ret
+ %cmp = icmp sgt i64 %a, %b
+ %cond = select i1 %cmp, i64 %a, i64 %b
+ ret i64 %cond
+}
+
+define i64 @min_i64(i64 %a, i64 %b) nounwind {
+; RV64I-LABEL: min_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: blt a0, a1, .LBB3_2
+; RV64I-NEXT: # %bb.1:
+; RV64I-NEXT: mv a0, a1
+; RV64I-NEXT: .LBB3_2:
+; RV64I-NEXT: ret
+;
+; RV64ZBPBO-LABEL: min_i64:
+; RV64ZBPBO: # %bb.0:
+; RV64ZBPBO-NEXT: min a0, a0, a1
+; RV64ZBPBO-NEXT: ret
+ %cmp = icmp slt i64 %a, %b
+ %cond = select i1 %cmp, i64 %a, i64 %b
+ ret i64 %cond
+}
+
+; TODO: rev8.h, rev
+
+define i64 @cmix_i64(i64 %a, i64 %b, i64 %c) nounwind {
+; RV64I-LABEL: cmix_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: and a0, a1, a0
+; RV64I-NEXT: not a1, a1
+; RV64I-NEXT: and a1, a1, a2
+; RV64I-NEXT: or a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBPBO-LABEL: cmix_i64:
+; RV64ZBPBO: # %bb.0:
+; RV64ZBPBO-NEXT: cmix a0, a1, a0, a2
+; RV64ZBPBO-NEXT: ret
+ %and = and i64 %b, %a
+ %neg = xor i64 %b, -1
+ %and1 = and i64 %neg, %c
+ %or = or i64 %and1, %and
+ ret i64 %or
+}
Index: llvm/test/CodeGen/RISCV/rv32zbpbo.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/rv32zbpbo.ll
@@ -0,0 +1,208 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbpbo -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV32ZBPBO
+
+declare i32 @llvm.ctlz.i32(i32, i1)
+
+define i32 @ctlz_i32(i32 %a) nounwind {
+; CHECK-LABEL: ctlz_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: addi sp, sp, -16
+; CHECK-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; CHECK-NEXT: beqz a0, .LBB0_2
+; CHECK-NEXT: # %bb.1: # %cond.false
+; CHECK-NEXT: srli a1, a0, 1
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: srli a1, a0, 2
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: srli a1, a0, 4
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: srli a1, a0, 8
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: srli a1, a0, 16
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: not a0, a0
+; CHECK-NEXT: srli a1, a0, 1
+; CHECK-NEXT: lui a2, 349525
+; CHECK-NEXT: addi a2, a2, 1365
+; CHECK-NEXT: and a1, a1, a2
+; CHECK-NEXT: sub a0, a0, a1
+; CHECK-NEXT: lui a1, 209715
+; CHECK-NEXT: addi a1, a1, 819
+; CHECK-NEXT: and a2, a0, a1
+; CHECK-NEXT: srli a0, a0, 2
+; CHECK-NEXT: and a0, a0, a1
+; CHECK-NEXT: add a0, a2, a0
+; CHECK-NEXT: srli a1, a0, 4
+; CHECK-NEXT: add a0, a0, a1
+; CHECK-NEXT: lui a1, 61681
+; CHECK-NEXT: addi a1, a1, -241
+; CHECK-NEXT: and a0, a0, a1
+; CHECK-NEXT: lui a1, 4112
+; CHECK-NEXT: addi a1, a1, 257
+; CHECK-NEXT: call __mulsi3@plt
+; CHECK-NEXT: srli a0, a0, 24
+; CHECK-NEXT: j .LBB0_3
+; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: li a0, 32
+; CHECK-NEXT: .LBB0_3: # %cond.end
+; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; CHECK-NEXT: addi sp, sp, 16
+; CHECK-NEXT: ret
+; RV32I-LABEL: ctlz_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: beqz a0, .LBB0_2
+; RV32I-NEXT: # %bb.1: # %cond.false
+; RV32I-NEXT: srli a1, a0, 1
+; RV32I-NEXT: or a0, a0, a1
+; RV32I-NEXT: srli a1, a0, 2
+; RV32I-NEXT: or a0, a0, a1
+; RV32I-NEXT: srli a1, a0, 4
+; RV32I-NEXT: or a0, a0, a1
+; RV32I-NEXT: srli a1, a0, 8
+; RV32I-NEXT: or a0, a0, a1
+; RV32I-NEXT: srli a1, a0, 16
+; RV32I-NEXT: or a0, a0, a1
+; RV32I-NEXT: not a0, a0
+; RV32I-NEXT: srli a1, a0, 1
+; RV32I-NEXT: lui a2, 349525
+; RV32I-NEXT: addi a2, a2, 1365
+; RV32I-NEXT: and a1, a1, a2
+; RV32I-NEXT: sub a0, a0, a1
+; RV32I-NEXT: lui a1, 209715
+; RV32I-NEXT: addi a1, a1, 819
+; RV32I-NEXT: and a2, a0, a1
+; RV32I-NEXT: srli a0, a0, 2
+; RV32I-NEXT: and a0, a0, a1
+; RV32I-NEXT: add a0, a2, a0
+; RV32I-NEXT: srli a1, a0, 4
+; RV32I-NEXT: add a0, a0, a1
+; RV32I-NEXT: lui a1, 61681
+; RV32I-NEXT: addi a1, a1, -241
+; RV32I-NEXT: and a0, a0, a1
+; RV32I-NEXT: lui a1, 4112
+; RV32I-NEXT: addi a1, a1, 257
+; RV32I-NEXT: call __mulsi3@plt
+; RV32I-NEXT: srli a0, a0, 24
+; RV32I-NEXT: j .LBB0_3
+; RV32I-NEXT: .LBB0_2:
+; RV32I-NEXT: li a0, 32
+; RV32I-NEXT: .LBB0_3: # %cond.end
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV32ZBPBO-LABEL: ctlz_i32:
+; RV32ZBPBO: # %bb.0:
+; RV32ZBPBO-NEXT: beqz a0, .LBB0_2
+; RV32ZBPBO-NEXT: # %bb.1: # %cond.false
+; RV32ZBPBO-NEXT: clz a0, a0
+; RV32ZBPBO-NEXT: ret
+; RV32ZBPBO-NEXT: .LBB0_2:
+; RV32ZBPBO-NEXT: li a0, 32
+; RV32ZBPBO-NEXT: ret
+ %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
+ ret i32 %1
+}
+
+define i32 @pack_i32(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: pack_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: slli a1, a1, 16
+; RV32I-NEXT: or a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBPBO-LABEL: pack_i32:
+; RV32ZBPBO: # %bb.0:
+; RV32ZBPBO-NEXT: pack a0, a0, a1
+; RV32ZBPBO-NEXT: ret
+ %shl = and i32 %a, 65535
+ %shl1 = shl i32 %b, 16
+ %or = or i32 %shl1, %shl
+ ret i32 %or
+}
+
+define i32 @packu_i32(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: packu_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: lui a2, 1048560
+; RV32I-NEXT: and a1, a1, a2
+; RV32I-NEXT: or a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBPBO-LABEL: packu_i32:
+; RV32ZBPBO: # %bb.0:
+; RV32ZBPBO-NEXT: packu a0, a0, a1
+; RV32ZBPBO-NEXT: ret
+ %shr = lshr i32 %a, 16
+ %shr1 = and i32 %b, -65536
+ %or = or i32 %shr1, %shr
+ ret i32 %or
+}
+
+; TODO: fsr,fsri
+
+define i32 @max_i32(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: max_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: blt a1, a0, .LBB3_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: mv a0, a1
+; RV32I-NEXT: .LBB3_2:
+; RV32I-NEXT: ret
+;
+; RV32ZBPBO-LABEL: max_i32:
+; RV32ZBPBO: # %bb.0:
+; RV32ZBPBO-NEXT: max a0, a0, a1
+; RV32ZBPBO-NEXT: ret
+ %cmp = icmp sgt i32 %a, %b
+ %cond = select i1 %cmp, i32 %a, i32 %b
+ ret i32 %cond
+}
+
+define i32 @min_i32(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: min_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: blt a0, a1, .LBB4_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: mv a0, a1
+; RV32I-NEXT: .LBB4_2:
+; RV32I-NEXT: ret
+;
+; RV32ZBPBO-LABEL: min_i32:
+; RV32ZBPBO: # %bb.0:
+; RV32ZBPBO-NEXT: min a0, a0, a1
+; RV32ZBPBO-NEXT: ret
+ %cmp = icmp slt i32 %a, %b
+ %cond = select i1 %cmp, i32 %a, i32 %b
+ ret i32 %cond
+}
+
+; TODO: rev8.h, rev
+
+define i32 @cmix_i32(i32 %a, i32 %b, i32 %c) nounwind {
+; RV32I-LABEL: cmix_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: and a0, a1, a0
+; RV32I-NEXT: not a1, a1
+; RV32I-NEXT: and a1, a1, a2
+; RV32I-NEXT: or a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBPBO-LABEL: cmix_i32:
+; RV32ZBPBO: # %bb.0:
+; RV32ZBPBO-NEXT: cmix a0, a1, a0, a2
+; RV32ZBPBO-NEXT: ret
+ %and = and i32 %b, %a
+ %neg = xor i32 %b, -1
+ %and1 = and i32 %neg, %c
+ %or = or i32 %and1, %and
+ ret i32 %or
+}
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -60,6 +60,7 @@
bool HasStdExtZbr = false;
bool HasStdExtZbs = false;
bool HasStdExtZbt = false;
+ bool HasStdExtZbpbo = false;
bool HasStdExtV = false;
bool HasStdExtZve32x = false;
bool HasStdExtZve32f = false;
@@ -158,6 +159,7 @@
bool hasStdExtZbf() const { return HasStdExtZbf; }
bool hasStdExtZbm() const { return HasStdExtZbm; }
bool hasStdExtZbp() const { return HasStdExtZbp; }
+ bool hasStdExtZbpbo() const { return HasStdExtZbpbo; }
bool hasStdExtZbr() const { return HasStdExtZbr; }
bool hasStdExtZbs() const { return HasStdExtZbs; }
bool hasStdExtZbt() const { return HasStdExtZbt; }
Index: llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -451,34 +451,41 @@
} // Predicates = [HasStdExtZbpOrZbkx]
let Predicates = [HasStdExtZbt] in {
-def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
- Sched<[WriteCMix, ReadCMix, ReadCMix, ReadCMix]>;
def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
Sched<[WriteCMov, ReadCMov, ReadCMov, ReadCMov]>;
def FSL : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
Sched<[WriteFSReg, ReadFSReg, ReadFSReg, ReadFSReg]>;
+} // Predicates = [HasStdExtZbt]
+
+let Predicates = [HasStdExtZbtOrZbpbo] in {
+def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
+ Sched<[WriteCMix, ReadCMix, ReadCMix, ReadCMix]>;
def FSR : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
Sched<[WriteFSReg, ReadFSReg, ReadFSReg, ReadFSReg]>;
def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
"$rd, $rs1, $rs3, $shamt">,
Sched<[WriteFSRImm, ReadFSRImm, ReadFSRImm]>;
-} // Predicates = [HasStdExtZbt]
+} // Predicates = [HasStdExtZbtOrZbpbo]
let Predicates = [HasStdExtZbt, IsRV64] in {
def FSLW : RVBTernaryR<0b10, 0b001, OPC_OP_32,
"fslw", "$rd, $rs1, $rs3, $rs2">,
Sched<[WriteFSReg32, ReadFSReg32, ReadFSReg32, ReadFSReg32]>;
-def FSRW : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
- "$rd, $rs1, $rs3, $rs2">,
- Sched<[WriteFSReg32, ReadFSReg32, ReadFSReg32, ReadFSReg32]>;
def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
"fsriw", "$rd, $rs1, $rs3, $shamt">,
Sched<[WriteFSRImm32, ReadFSRImm32, ReadFSRImm32]>;
} // Predicates = [HasStdExtZbt, IsRV64]
-let Predicates = [HasStdExtZbb] in {
+let Predicates = [HasStdExtZbtOrZbpbo, IsRV64] in
+def FSRW : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
+ "$rd, $rs1, $rs3, $rs2">,
+ Sched<[WriteFSReg32, ReadFSReg32, ReadFSReg32, ReadFSReg32]>;
+
+let Predicates = [HasStdExtZbbOrZbpbo] in
def CLZ : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM, "clz">,
Sched<[WriteCLZ, ReadCLZ]>;
+
+let Predicates = [HasStdExtZbb] in {
def CTZ : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM, "ctz">,
Sched<[WriteCTZ, ReadCTZ]>;
def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM, "cpop">,
@@ -537,13 +544,16 @@
Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
} // Predicates = [HasStdExtZbcOrZbkc]
-let Predicates = [HasStdExtZbb] in {
+let Predicates = [HasStdExtZbbOrZbpbo] in {
def MIN : ALU_rr<0b0000101, 0b100, "min", /*Commutable*/1>,
Sched<[WriteIALU, ReadIALU, ReadIALU]>;
-def MINU : ALU_rr<0b0000101, 0b101, "minu", /*Commutable*/1>,
- Sched<[WriteIALU, ReadIALU, ReadIALU]>;
def MAX : ALU_rr<0b0000101, 0b110, "max", /*Commutable*/1>,
Sched<[WriteIALU, ReadIALU, ReadIALU]>;
+} // Predicates = [HasStdExtZbbOrZbpbo]
+
+let Predicates = [HasStdExtZbb] in {
+def MINU : ALU_rr<0b0000101, 0b101, "minu", /*Commutable*/1>,
+ Sched<[WriteIALU, ReadIALU, ReadIALU]>;
def MAXU : ALU_rr<0b0000101, 0b111, "maxu", /*Commutable*/1>,
Sched<[WriteIALU, ReadIALU, ReadIALU]>;
} // Predicates = [HasStdExtZbb]
@@ -566,18 +576,19 @@
Sched<[WriteCompress32, ReadCompress32, ReadCompress32]>;
} // Predicates = [HasStdExtZbe, IsRV64]
-let Predicates = [HasStdExtZbpOrZbkb] in {
+let Predicates = [HasStdExtZbpOrZbkbOrZbpbo] in
def PACK : ALU_rr<0b0000100, 0b100, "pack">,
Sched<[WritePACK, ReadPACK, ReadPACK]>;
+
+let Predicates = [HasStdExtZbpOrZbkb] in
def PACKH : ALU_rr<0b0000100, 0b111, "packh">,
Sched<[WritePACK, ReadPACK, ReadPACK]>;
-} // Predicates = [HasStdExtZbpOrZbkb]
let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in
def PACKW : ALUW_rr<0b0000100, 0b100, "packw">,
Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;
-let Predicates = [HasStdExtZbp] in
+let Predicates = [HasStdExtZbpOrZbpbo] in
def PACKU : ALU_rr<0b0100100, 0b100, "packu">,
Sched<[WritePACKU, ReadPACKU, ReadPACKU]>;
@@ -692,6 +703,9 @@
def : InstAlias<"orc.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
} // Predicates = [HasStdExtZbp]
+let Predicates = [HasStdExtZbpOrZbpbo] in
+def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
+
let Predicates = [HasStdExtZbp, IsRV32] in {
def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
// rev8 is considered an instruction rather than an alias.
@@ -714,6 +728,11 @@
def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
} // Predicates = [HasStdExtZbp, IsRV32]
+let Predicates = [HasStdExtZbpOrZbpbo, IsRV32] in
+def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
+let Predicates = [HasStdExtZbpOrZbpbo, IsRV64] in
+def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
+
let Predicates = [HasStdExtZbp, IsRV64] in {
def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
def : InstAlias<"rev8.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
@@ -948,12 +967,14 @@
def : Pat<(i64 (riscv_grev GPR:$rs1, 56)), (REV8_RV64 GPR:$rs1)>;
} // Predicates = [HasStdExtZbp, IsRV64]
-let Predicates = [HasStdExtZbt] in {
+let Predicates = [HasStdExtZbtOrZbpbo] in {
def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
(CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(xor (and (xor GPR:$rs1, GPR:$rs3), GPR:$rs2), GPR:$rs3),
(CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
+} // Predicates = [HasStdExtZbtOrZbpbo]
+let Predicates = [HasStdExtZbt] in {
def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3),
(CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1),
@@ -985,9 +1006,11 @@
(CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
} // Predicates = [HasStdExtZbt]
-let Predicates = [HasStdExtZbt] in {
+let Predicates = [HasStdExtZbt] in
def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
+
+let Predicates = [HasStdExtZbtOrZbpbo] in {
def : Pat<(riscv_fsr GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(riscv_fsr GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
@@ -996,13 +1019,15 @@
// XLen and swap the operands.
def : Pat<(riscv_fsl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
(FSRI GPR:$rs1, GPR:$rs3, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
-} // Predicates = [HasStdExtZbt]
+} // Predicates = [HasStdExtZbtOrZbpbo]
+
+let Predicates = [HasStdExtZbtOrZbpbo, IsRV64] in
+def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, GPR:$rs2),
+ (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
let Predicates = [HasStdExtZbt, IsRV64] in {
def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
-def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, GPR:$rs2),
- (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, uimm5:$shamt),
(FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
// We can use FSRIW for FSLW by immediate if we subtract the immediate from
@@ -1011,8 +1036,10 @@
(FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
} // Predicates = [HasStdExtZbt, IsRV64]
-let Predicates = [HasStdExtZbb] in {
+let Predicates = [HasStdExtZbbOrZbpbo] in
def : PatGpr<ctlz, CLZ>;
+
+let Predicates = [HasStdExtZbb] in {
def : PatGpr<cttz, CTZ>;
def : PatGpr<ctpop, CPOP>;
} // Predicates = [HasStdExtZbb]
@@ -1028,9 +1055,12 @@
def : Pat<(sext_inreg GPR:$rs1, i16), (SEXT_H GPR:$rs1)>;
} // Predicates = [HasStdExtZbb]
-let Predicates = [HasStdExtZbb] in {
+let Predicates = [HasStdExtZbbOrZbpbo] in {
def : PatGprGpr<smin, MIN>;
def : PatGprGpr<smax, MAX>;
+} // Predicates = [HasStdExtZbbOrZbpbo]
+
+let Predicates = [HasStdExtZbb] in {
def : PatGprGpr<umin, MINU>;
def : PatGprGpr<umax, MAXU>;
} // Predicates = [HasStdExtZbb]
@@ -1052,14 +1082,15 @@
(PACKH GPR:$rs1, GPR:$rs2)>;
} // Predicates = [HasStdExtZbpOrZbkb]
-let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in
+let Predicates = [HasStdExtZbpOrZbkbOrZbpbo, IsRV32] in
def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
(PACK GPR:$rs1, GPR:$rs2)>;
-let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in {
+let Predicates = [HasStdExtZbpOrZbkbOrZbpbo, IsRV64] in
def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
(PACK GPR:$rs1, GPR:$rs2)>;
+let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in {
def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
(and GPR:$rs1, 0x000000000000FFFF)),
i32)),
@@ -1069,18 +1100,18 @@
(PACKW GPR:$rs1, GPR:$rs2)>;
} // Predicates = [HasStdExtZbpOrZbkb, IsRV64]
-let Predicates = [HasStdExtZbp, IsRV32] in
+let Predicates = [HasStdExtZbpOrZbpbo, IsRV32] in
def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
(PACKU GPR:$rs1, GPR:$rs2)>;
-let Predicates = [HasStdExtZbp, IsRV64] in {
+let Predicates = [HasStdExtZbpOrZbpbo, IsRV64] in
def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
(PACKU GPR:$rs1, GPR:$rs2)>;
+let Predicates = [HasStdExtZbp, IsRV64] in
def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
(srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
(PACKUW GPR:$rs1, GPR:$rs2)>;
-} // Predicates = [HasStdExtZbp, IsRV64]
let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -283,6 +283,10 @@
if (Subtarget.is64Bit())
setOperationAction(ISD::ABS, MVT::i32, Custom);
}
+ if (Subtarget.hasStdExtZbpbo()) {
+ setOperationAction({ISD::SMIN, ISD::SMAX}, XLenVT, Legal);
+ setOperationAction(ISD::CTLZ, MVT::i32, Legal);
+ }
if (Subtarget.hasStdExtZbt()) {
setOperationAction({ISD::FSHL, ISD::FSHR}, XLenVT, Custom);
@@ -294,6 +298,9 @@
setOperationAction(ISD::SELECT, XLenVT, Custom);
}
+ if (Subtarget.hasStdExtZbt())
+ setOperationAction({ISD::FSHL, ISD::FSHR}, XLenVT, Custom);
+
static constexpr ISD::NodeType FPLegalNodeTypes[] = {
ISD::FMINNUM, ISD::FMAXNUM, ISD::LRINT,
ISD::LLRINT, ISD::LROUND, ISD::LLROUND,
Index: llvm/lib/Target/RISCV/RISCV.td
===================================================================
--- llvm/lib/Target/RISCV/RISCV.td
+++ llvm/lib/Target/RISCV/RISCV.td
@@ -247,6 +247,41 @@
"'Zbc' (Carry-Less Multiplication) or "
"'Zbkc' (Carry-less multiply instructions for Cryptography)">;
+def FeatureStdExtZbpbo
+ : SubtargetFeature<"experimental-zbpbo", "HasStdExtZbpbo", "true",
+ "'Zbpbo' ('B' & 'P' Overlay Instructions)">;
+def HasStdExtZbpbo
+ : Predicate<"Subtarget->hasStdExtZbpbo()">,
+ AssemblerPredicate<(all_of FeatureStdExtZbpbo),
+ "'Zbpbo' ('B' & 'P' Overlay Instructions)">;
+
+def HasStdExtZbbOrZbpbo
+ : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbpbo()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbpbo),
+ "'Zbb' (Basic Bit-Manipulation) or "
+ "'Zbpbo' ('B' & 'P' Overlay Instructions)">;
+
+def HasStdExtZbpOrZbpbo
+ : Predicate<"Subtarget->hasStdExtZbp() || Subtarget->hasStdExtZbpbo()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbp, FeatureStdExtZbpbo),
+ "'Zbp' (Permutation 'Zb' Instructions) or "
+ "'Zbpbo' ('B' & 'P' Overlay Instructions)">;
+
+def HasStdExtZbpOrZbkbOrZbpbo
+ : Predicate<"Subtarget->hasStdExtZbp() || Subtarget->hasStdExtZbkb()"
+ "|| Subtarget->hasStdExtZbpbo()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbp, FeatureStdExtZbkb,
+ FeatureStdExtZbpbo),
+ "'Zbp' (Permutation 'Zb' Instructions) or "
+ "'Zbkb' (Bitmanip instructions for Cryptography) or "
+ "'Zbpbo' ('B' & 'P' Overlay Instructions)">;
+
+def HasStdExtZbtOrZbpbo
+ : Predicate<"Subtarget->hasStdExtZbt() || Subtarget->hasStdExtZbpbo()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbt, FeatureStdExtZbpbo),
+ "'Zbt' (Ternary 'Zb' Instructions) or "
+ "'Zbpbo' ('B' & 'P' Overlay Instructions)">;
+
def FeatureStdExtZknd
: SubtargetFeature<"zknd", "HasStdExtZknd", "true",
"'Zknd' (NIST Suite: AES Decryption)">;
Index: llvm/lib/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -104,6 +104,7 @@
{"zbp", RISCVExtensionVersion{0, 93}},
{"zbr", RISCVExtensionVersion{0, 93}},
{"zbt", RISCVExtensionVersion{0, 93}},
+ {"zbpbo", RISCVExtensionVersion{0, 911}},
{"zvfh", RISCVExtensionVersion{0, 1}},
};
Index: clang/test/CodeGen/RISCV/rvp-intrinsics/riscv64-zbpbo.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/RISCV/rvp-intrinsics/riscv64-zbpbo.c
@@ -0,0 +1,33 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -no-opaque-pointers -triple riscv64 -target-feature +experimental-zbpbo -emit-llvm %s -o - \
+// RUN: | FileCheck %s -check-prefix=RV64ZBPBO
+
+// RV64ZBPBO-LABEL: @fsrw(
+// RV64ZBPBO-NEXT: entry:
+// RV64ZBPBO-NEXT: [[RS1_ADDR:%.*]] = alloca i64, align 8
+// RV64ZBPBO-NEXT: [[RS2_ADDR:%.*]] = alloca i64, align 8
+// RV64ZBPBO-NEXT: [[RS3_ADDR:%.*]] = alloca i64, align 8
+// RV64ZBPBO-NEXT: store i64 [[RS1:%.*]], i64* [[RS1_ADDR]], align 8
+// RV64ZBPBO-NEXT: store i64 [[RS2:%.*]], i64* [[RS2_ADDR]], align 8
+// RV64ZBPBO-NEXT: store i64 [[RS3:%.*]], i64* [[RS3_ADDR]], align 8
+// RV64ZBPBO-NEXT: [[TMP0:%.*]] = load i64, i64* [[RS1_ADDR]], align 8
+// RV64ZBPBO-NEXT: [[TMP1:%.*]] = load i64, i64* [[RS2_ADDR]], align 8
+// RV64ZBPBO-NEXT: [[TMP2:%.*]] = load i64, i64* [[RS3_ADDR]], align 8
+// RV64ZBPBO-NEXT: [[TMP3:%.*]] = call i64 @llvm.riscv.fsr.i64(i64 [[TMP0]], i64 [[TMP1]], i64 [[TMP2]])
+// RV64ZBPBO-NEXT: ret i64 [[TMP3]]
+//
+long fsrw(long rs1, long rs2, long rs3) {
+ return __builtin_riscv_fsr_64(rs1, rs2, rs3);
+}
+
+// RV64ZBPBO-LABEL: @grevi(
+// RV64ZBPBO-NEXT: entry:
+// RV64ZBPBO-NEXT: [[RS1_ADDR:%.*]] = alloca i64, align 8
+// RV64ZBPBO-NEXT: store i64 [[RS1:%.*]], i64* [[RS1_ADDR]], align 8
+// RV64ZBPBO-NEXT: [[TMP0:%.*]] = load i64, i64* [[RS1_ADDR]], align 8
+// RV64ZBPBO-NEXT: [[TMP1:%.*]] = call i64 @llvm.riscv.grev.i64(i64 [[TMP0]], i64 13)
+// RV64ZBPBO-NEXT: ret i64 [[TMP1]]
+//
+long grevi(long rs1) {
+ return __builtin_riscv_grev_64(rs1, 13);
+}
Index: clang/test/CodeGen/RISCV/rvp-intrinsics/riscv32-zbpbo.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/RISCV/rvp-intrinsics/riscv32-zbpbo.c
@@ -0,0 +1,60 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -no-opaque-pointers -triple riscv32 -target-feature +experimental-zbpbo -emit-llvm %s -o - \
+// RUN: | FileCheck %s -check-prefix=RV32ZBPBO
+
+// RV32ZBPBO-LABEL: @clz_32(
+// RV32ZBPBO-NEXT: entry:
+// RV32ZBPBO-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP0]], i1 false)
+// RV32ZBPBO-NEXT: ret i32 [[TMP1]]
+//
+int clz_32(int a) {
+ return __builtin_riscv_clz_32(a);
+}
+
+// RV32ZBPBO-LABEL: @fsr(
+// RV32ZBPBO-NEXT: entry:
+// RV32ZBPBO-NEXT: [[RS1_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: [[RS2_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: [[RS3_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: store i32 [[RS1:%.*]], i32* [[RS1_ADDR]], align 4
+// RV32ZBPBO-NEXT: store i32 [[RS2:%.*]], i32* [[RS2_ADDR]], align 4
+// RV32ZBPBO-NEXT: store i32 [[RS3:%.*]], i32* [[RS3_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP0:%.*]] = load i32, i32* [[RS1_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP1:%.*]] = load i32, i32* [[RS2_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP2:%.*]] = load i32, i32* [[RS3_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP3:%.*]] = call i32 @llvm.riscv.fsr.i32(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]])
+// RV32ZBPBO-NEXT: ret i32 [[TMP3]]
+//
+int fsr(int rs1, int rs2, int rs3) {
+ return __builtin_riscv_fsr_32(rs1, rs2, rs3);
+}
+
+// RV32ZBPBO-LABEL: @fsri(
+// RV32ZBPBO-NEXT: entry:
+// RV32ZBPBO-NEXT: [[RS1_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: [[RS2_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: store i32 [[RS1:%.*]], i32* [[RS1_ADDR]], align 4
+// RV32ZBPBO-NEXT: store i32 [[RS2:%.*]], i32* [[RS2_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP0:%.*]] = load i32, i32* [[RS1_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP1:%.*]] = load i32, i32* [[RS2_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.fsr.i32(i32 [[TMP0]], i32 [[TMP1]], i32 15)
+// RV32ZBPBO-NEXT: ret i32 [[TMP2]]
+//
+int fsri(int rs1, int rs2) {
+ return __builtin_riscv_fsr_32(rs1, rs2, 15);
+}
+
+// RV32ZBPBO-LABEL: @grevi(
+// RV32ZBPBO-NEXT: entry:
+// RV32ZBPBO-NEXT: [[RS1_ADDR:%.*]] = alloca i32, align 4
+// RV32ZBPBO-NEXT: store i32 [[RS1:%.*]], i32* [[RS1_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP0:%.*]] = load i32, i32* [[RS1_ADDR]], align 4
+// RV32ZBPBO-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.grev.i32(i32 [[TMP0]], i32 13)
+// RV32ZBPBO-NEXT: ret i32 [[TMP1]]
+//
+long grevi(long rs1) {
+ return __builtin_riscv_grev_32(rs1, 13);
+}
Index: clang/include/clang/Basic/BuiltinsRISCV.def
===================================================================
--- clang/include/clang/Basic/BuiltinsRISCV.def
+++ clang/include/clang/Basic/BuiltinsRISCV.def
@@ -18,7 +18,7 @@
// Zbb extension
TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "zbb")
TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "zbb,64bit")
-TARGET_BUILTIN(__builtin_riscv_clz_32, "ZiZi", "nc", "zbb")
+TARGET_BUILTIN(__builtin_riscv_clz_32, "ZiZi", "nc", "zbb|experimental-zbpbo")
TARGET_BUILTIN(__builtin_riscv_clz_64, "WiWi", "nc", "zbb,64bit")
TARGET_BUILTIN(__builtin_riscv_ctz_32, "ZiZi", "nc", "zbb")
TARGET_BUILTIN(__builtin_riscv_ctz_64, "WiWi", "nc", "zbb,64bit")
@@ -46,8 +46,10 @@
TARGET_BUILTIN(__builtin_riscv_bfp_64, "WiWiWi", "nc", "experimental-zbf,64bit")
// Zbp extension
-TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp,64bit")
+TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc",
+ "experimental-zbp|experimental-zbpbo")
+TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc",
+ "experimental-zbp|experimental-zbpbo,64bit")
TARGET_BUILTIN(__builtin_riscv_gorc_32, "ZiZiZi", "nc", "experimental-zbp")
TARGET_BUILTIN(__builtin_riscv_gorc_64, "WiWiWi", "nc", "experimental-zbp,64bit")
TARGET_BUILTIN(__builtin_riscv_shfl_32, "ZiZiZi", "nc", "experimental-zbp")
@@ -71,9 +73,11 @@
// Zbt extension
TARGET_BUILTIN(__builtin_riscv_fsl_32, "LiLiLiLi", "nc", "experimental-zbt")
-TARGET_BUILTIN(__builtin_riscv_fsr_32, "LiLiLiLi", "nc", "experimental-zbt")
+TARGET_BUILTIN(__builtin_riscv_fsr_32, "LiLiLiLi", "nc",
+ "experimental-zbt|experimental-zbpbo")
TARGET_BUILTIN(__builtin_riscv_fsl_64, "WiWiWiWi", "nc", "experimental-zbt,64bit")
-TARGET_BUILTIN(__builtin_riscv_fsr_64, "WiWiWiWi", "nc", "experimental-zbt,64bit")
+TARGET_BUILTIN(__builtin_riscv_fsr_64, "WiWiWiWi", "nc",
+ "experimental-zbt|experimental-zbpbo,64bit")
// Zbkb extension
TARGET_BUILTIN(__builtin_riscv_brev8, "LiLi", "nc", "zbkb")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits