[llvm] 5e85a2b - [PowerPC] Implement intrinsic for DARN instruction

Qiu Chaofan via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 7 22:13:42 PST 2020


Author: Qiu Chaofan
Date: 2020-12-08T14:08:52+08:00
New Revision: 5e85a2ba1645c3edbf26bba096631fbd318ada47

URL: https://github.com/llvm/llvm-project/commit/5e85a2ba1645c3edbf26bba096631fbd318ada47
DIFF: https://github.com/llvm/llvm-project/commit/5e85a2ba1645c3edbf26bba096631fbd318ada47.diff

LOG: [PowerPC] Implement intrinsic for DARN instruction

Instruction darn was introduced in ISA 3.0. It means 'Deliver A Random
Number'. The immediate number L means:

- L=0, the number is 32-bit (higher 32-bits are all-zero)
- L=1, the number is 'conditioned' (processed by hardware to reduce bias)
- L=2, the number is not conditioned, directly from noise source

GCC implements them in three separate intrinsics: __builtin_darn,
__builtin_darn_32 and __builtin_darn_raw. This patch implements the
same intrinsics. And this change also addresses Bugzilla PR39800.

Reviewed By: steven.zhang

Differential Revision: https://reviews.llvm.org/D92465

Added: 
    llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll

Modified: 
    clang/include/clang/Basic/BuiltinsPPC.def
    clang/test/CodeGen/builtins-ppc.c
    llvm/include/llvm/IR/IntrinsicsPowerPC.td
    llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index 78ce77043b6f..8975d126b897 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -638,6 +638,11 @@ BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "")
 BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "")
 BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "")
 
+// Generate random number
+BUILTIN(__builtin_darn, "LLi", "")
+BUILTIN(__builtin_darn_raw, "LLi", "")
+BUILTIN(__builtin_darn_32, "i", "")
+
 // Vector int128 (un)pack
 BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
 BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")

diff  --git a/clang/test/CodeGen/builtins-ppc.c b/clang/test/CodeGen/builtins-ppc.c
index e30cdff3c8ce..0abd540013e2 100644
--- a/clang/test/CodeGen/builtins-ppc.c
+++ b/clang/test/CodeGen/builtins-ppc.c
@@ -36,3 +36,16 @@ void test_builtin_ppc_flm() {
   // CHECK: call double @llvm.ppc.setflm(double %1)
   res = __builtin_setflm(res);
 }
+
+void test_builtin_ppc_darn() {
+  volatile long res;
+  volatile int x;
+  // CHECK: call i64 @llvm.ppc.darn()
+  res = __builtin_darn();
+
+  // CHECK: call i64 @llvm.ppc.darnraw()
+  res = __builtin_darn_raw();
+
+  // CHECK: call i32 @llvm.ppc.darn32()
+  x = __builtin_darn_32();
+}

diff  --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 8db5c15fe761..d559c000fd93 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -70,6 +70,14 @@ let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".
                        Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
                                  [IntrNoMem]>;
 
+  // Generate a random number
+  def int_ppc_darn : GCCBuiltin<"__builtin_darn">,
+                     Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+  def int_ppc_darnraw : GCCBuiltin<"__builtin_darn_raw">,
+                     Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+  def int_ppc_darn32 : GCCBuiltin<"__builtin_darn_32">,
+                     Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+
   // Bit permute doubleword
   def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">,
                        Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],

diff  --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 82b868ec2b10..9265c513c031 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -1606,6 +1606,11 @@ def : Pat<(atomic_store_64 iaddrX4:$ptr, i64:$val), (STD  g8rc:$val, memrix:$ptr
 def : Pat<(atomic_store_64 xaddrX4:$ptr,  i64:$val), (STDX g8rc:$val, memrr:$ptr)>;
 
 let Predicates = [IsISA3_0] in {
+// DARN (deliver random number)
+// L=0 for 32-bit, L=1 for conditioned random, L=2 for raw random
+def : Pat<(int_ppc_darn32), (EXTRACT_SUBREG (DARN 0), sub_32)>;
+def : Pat<(int_ppc_darn), (DARN 1)>;
+def : Pat<(int_ppc_darnraw), (DARN 2)>;
 
 class X_L1_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, RegisterOperand ty,
                    InstrItinClass itin, list<dag> pattern>

diff  --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll
new file mode 100644
index 000000000000..d53b442fef71
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -verify-machineinstrs -mtriple powerpc64le -mcpu=pwr9 | FileCheck %s
+
+define i64 @raw() {
+; CHECK-LABEL: raw:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    darn 3, 2
+; CHECK-NEXT:    blr
+entry:
+  %0 = call i64 @llvm.ppc.darnraw()
+  ret i64 %0
+}
+
+define i64 @conditioned() {
+; CHECK-LABEL: conditioned:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    darn 3, 1
+; CHECK-NEXT:    blr
+entry:
+  %0 = call i64 @llvm.ppc.darn()
+  ret i64 %0
+}
+
+define signext i32 @word() {
+; CHECK-LABEL: word:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    darn 3, 0
+; CHECK-NEXT:    extsw 3, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = call i32 @llvm.ppc.darn32()
+  ret i32 %0
+}
+
+declare i64 @llvm.ppc.darn()
+declare i64 @llvm.ppc.darnraw()
+declare i32 @llvm.ppc.darn32()


        


More information about the llvm-commits mailing list