[clang] 079757b - [PowerPC] Implement Vector String Isolate Builtins in Clang/LLVM

Amy Kwan via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 22 09:32:35 PDT 2020


Author: Amy Kwan
Date: 2020-09-22T11:31:44-05:00
New Revision: 079757b551f3ab5218af7344a7ab3c79976ec478

URL: https://github.com/llvm/llvm-project/commit/079757b551f3ab5218af7344a7ab3c79976ec478
DIFF: https://github.com/llvm/llvm-project/commit/079757b551f3ab5218af7344a7ab3c79976ec478.diff

LOG: [PowerPC] Implement Vector String Isolate Builtins in Clang/LLVM

This patch implements the vector string isolate (predicate and non-predicate
versions) builtins. The predicate builtins are custom selected within PPCISelDAGToDAG.

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

Added: 
    

Modified: 
    clang/include/clang/Basic/BuiltinsPPC.def
    clang/lib/Headers/altivec.h
    clang/test/CodeGen/builtins-ppc-p10vector.c
    llvm/include/llvm/IR/IntrinsicsPowerPC.td
    llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/lib/Target/PowerPC/PPCInstrPrefix.td
    llvm/test/CodeGen/PowerPC/p10-string-ops.ll

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index dea547a6e121..b571454cfc7a 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -348,6 +348,16 @@ BUILTIN(__builtin_altivec_mtvsrqm, "V1ULLLiULLi", "")
 BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "")
 BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "")
 
+// P10 Vector String Isolate Built-ins.
+BUILTIN(__builtin_altivec_vstribr, "V16cV16c", "")
+BUILTIN(__builtin_altivec_vstribl, "V16cV16c", "")
+BUILTIN(__builtin_altivec_vstrihr, "V8sV8s", "")
+BUILTIN(__builtin_altivec_vstrihl, "V8sV8s", "")
+BUILTIN(__builtin_altivec_vstribr_p, "iiV16c", "")
+BUILTIN(__builtin_altivec_vstribl_p, "iiV16c", "")
+BUILTIN(__builtin_altivec_vstrihr_p, "iiV8s", "")
+BUILTIN(__builtin_altivec_vstrihl_p, "iiV8s", "")
+
 // P10 Vector Centrifuge built-in.
 BUILTIN(__builtin_altivec_vcfuged, "V2ULLiV2ULLiV2ULLi", "")
 

diff  --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h
index 010a00e15b74..2c09e477bd3c 100644
--- a/clang/lib/Headers/altivec.h
+++ b/clang/lib/Headers/altivec.h
@@ -17636,6 +17636,150 @@ vec_test_lsbb_all_zeros(vector unsigned char __a) {
 }
 #endif /* __VSX__ */
 
+/* vec_stril */
+
+static __inline__ vector unsigned char __ATTRS_o_ai
+vec_stril(vector unsigned char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribr((vector signed char)__a);
+#else
+  return __builtin_altivec_vstribl((vector signed char)__a);
+#endif
+}
+
+static __inline__ vector signed char __ATTRS_o_ai
+vec_stril(vector signed char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribr(__a);
+#else
+  return __builtin_altivec_vstribl(__a);
+#endif
+}
+
+static __inline__ vector unsigned short __ATTRS_o_ai
+vec_stril(vector unsigned short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihr((vector signed short)__a);
+#else
+  return __builtin_altivec_vstrihl((vector signed short)__a);
+#endif
+}
+
+static __inline__ vector signed short __ATTRS_o_ai
+vec_stril(vector signed short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihr(__a);
+#else
+  return __builtin_altivec_vstrihl(__a);
+#endif
+}
+
+/* vec_stril_p */
+
+static __inline__ int __ATTRS_o_ai vec_stril_p(vector unsigned char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribr_p(__CR6_EQ, (vector signed char)__a);
+#else
+  return __builtin_altivec_vstribl_p(__CR6_EQ, (vector signed char)__a);
+#endif
+}
+
+static __inline__ int __ATTRS_o_ai vec_stril_p(vector signed char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribr_p(__CR6_EQ, __a);
+#else
+  return __builtin_altivec_vstribl_p(__CR6_EQ, __a);
+#endif
+}
+
+static __inline__ int __ATTRS_o_ai vec_stril_p(vector unsigned short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihr_p(__CR6_EQ, (vector signed short)__a);
+#else
+  return __builtin_altivec_vstrihl_p(__CR6_EQ, (vector signed short)__a);
+#endif
+}
+
+static __inline__ int __ATTRS_o_ai vec_stril_p(vector signed short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihr_p(__CR6_EQ, __a);
+#else
+  return __builtin_altivec_vstrihl_p(__CR6_EQ, __a);
+#endif
+}
+
+/* vec_strir */
+
+static __inline__ vector unsigned char __ATTRS_o_ai
+vec_strir(vector unsigned char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribl((vector signed char)__a);
+#else
+  return __builtin_altivec_vstribr((vector signed char)__a);
+#endif
+}
+
+static __inline__ vector signed char __ATTRS_o_ai
+vec_strir(vector signed char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribl(__a);
+#else
+  return __builtin_altivec_vstribr(__a);
+#endif
+}
+
+static __inline__ vector unsigned short __ATTRS_o_ai
+vec_strir(vector unsigned short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihl((vector signed short)__a);
+#else
+  return __builtin_altivec_vstrihr((vector signed short)__a);
+#endif
+}
+
+static __inline__ vector signed short __ATTRS_o_ai
+vec_strir(vector signed short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihl(__a);
+#else
+  return __builtin_altivec_vstrihr(__a);
+#endif
+}
+
+/* vec_strir_p */
+
+static __inline__ int __ATTRS_o_ai vec_strir_p(vector unsigned char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribl_p(__CR6_EQ, (vector signed char)__a);
+#else
+  return __builtin_altivec_vstribr_p(__CR6_EQ, (vector signed char)__a);
+#endif
+}
+
+static __inline__ int __ATTRS_o_ai vec_strir_p(vector signed char __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstribl_p(__CR6_EQ, __a);
+#else
+  return __builtin_altivec_vstribr_p(__CR6_EQ, __a);
+#endif
+}
+
+static __inline__ int __ATTRS_o_ai vec_strir_p(vector unsigned short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihl_p(__CR6_EQ, (vector signed short)__a);
+#else
+  return __builtin_altivec_vstrihr_p(__CR6_EQ, (vector signed short)__a);
+#endif
+}
+
+static __inline__ int __ATTRS_o_ai vec_strir_p(vector signed short __a) {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vstrihl_p(__CR6_EQ, __a);
+#else
+  return __builtin_altivec_vstrihr_p(__CR6_EQ, __a);
+#endif
+}
+
 /* vs[l | r | ra] */
 
 static __inline__ vector unsigned __int128 __ATTRS_o_ai

diff  --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c
index 2f96cdfd9d68..89f49adf28e9 100644
--- a/clang/test/CodeGen/builtins-ppc-p10vector.c
+++ b/clang/test/CodeGen/builtins-ppc-p10vector.c
@@ -190,6 +190,318 @@ vector unsigned long long test_vpextd(void) {
   return vec_pext(vulla, vullb);
 }
 
+vector unsigned char test_vec_stril_uc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret <16 x i8>
+  // CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret <16 x i8>
+  return vec_stril(vuca);
+}
+
+vector signed char test_vec_stril_sc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret <16 x i8>
+  // CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret <16 x i8>
+  return vec_stril(vsca);
+}
+
+vector unsigned short test_vec_stril_us(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret <8 x i16>
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret <8 x i16>
+  return vec_stril(vusa);
+}
+
+vector signed short test_vec_stril_ss(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret <8 x i16>
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret <8 x i16>
+  return vec_stril(vssa);
+}
+
+int test_vec_stril_p_uc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_stril_p(vuca);
+}
+
+int test_vec_stril_p_sc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_stril_p(vsca);
+}
+
+int test_vec_stril_p_us(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_stril_p(vusa);
+}
+
+int test_vec_stril_p_ss(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_stril_p(vssa);
+}
+
+vector unsigned char test_vec_stril_p_uc_2(vector unsigned char *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-BE: ret <16 x i8>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-LE: ret <16 x i8>
+  for (int i = 0; i < len; i++) {
+    if (vec_stril_p(*(ptr + i))) {
+      return vec_stril(*(ptr + i));
+    }
+  }
+  return vec_stril(*(ptr));
+}
+
+vector signed char test_vec_stril_p_sc_2(vector signed char *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-BE: ret <16 x i8>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-LE: ret <16 x i8>
+  for (int i = 0; i < len; i++) {
+    if (vec_stril_p(*(ptr + i))) {
+      return vec_stril(*(ptr + i));
+    }
+  }
+  return vec_stril(*(ptr));
+}
+
+vector unsigned short test_vec_stril_p_us_2(vector unsigned short *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-BE: ret <8 x i16>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-LE: ret <8 x i16>
+  for (int i = 0; i < len; i++) {
+    if (vec_stril_p(*(ptr + i))) {
+      return vec_stril(*(ptr + i));
+    }
+  }
+  return vec_stril(*(ptr));
+}
+
+vector signed short test_vec_stril_p_ss_2(vector signed short *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-BE: ret <8 x i16>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-LE: ret <8 x i16>
+  for (int i = 0; i < len; i++) {
+    if (vec_stril_p(*(ptr + i))) {
+      return vec_stril(*(ptr + i));
+    }
+  }
+  return vec_stril(*(ptr));
+}
+
+vector unsigned char test_vec_strir_uc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret <16 x i8>
+  // CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret <16 x i8>
+  return vec_strir(vuca);
+}
+
+vector signed char test_vec_strir_sc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret <16 x i8>
+  // CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret <16 x i8>
+  return vec_strir(vsca);
+}
+
+vector unsigned short test_vec_strir_us(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret <8 x i16>
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret <8 x i16>
+  return vec_strir(vusa);
+}
+
+vector signed short test_vec_strir_ss(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret <8 x i16>
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret <8 x i16>
+  return vec_strir(vssa);
+}
+
+int test_vec_strir_p_uc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_strir_p(vuca);
+}
+
+int test_vec_strir_p_sc(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_strir_p(vsca);
+}
+
+int test_vec_strir_p_us(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_strir_p(vusa);
+}
+
+int test_vec_strir_p_ss(void) {
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE-NEXT: ret i32
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE-NEXT: ret i32
+  return vec_strir_p(vssa);
+}
+
+vector unsigned char test_vec_strir_p_uc_2(vector unsigned char *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-BE: ret <16 x i8>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-LE: ret <16 x i8>
+  for (int i = 0; i < len; i++) {
+    if (vec_strir_p(*(ptr + i))) {
+      return vec_strir(*(ptr + i));
+    }
+  }
+  return vec_strir(*(ptr));
+}
+
+vector signed char test_vec_strir_p_sc_2(vector signed char *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstribr.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstribr(<16 x i8> %{{.+}})
+  // CHECK-BE: ret <16 x i8>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstribl.p(i32 0, <16 x i8> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstribl(<16 x i8> %{{.+}})
+  // CHECK-LE: ret <16 x i8>
+  for (int i = 0; i < len; i++) {
+    if (vec_strir_p(*(ptr + i))) {
+      return vec_strir(*(ptr + i));
+    }
+  }
+  return vec_strir(*(ptr));
+}
+
+vector unsigned short test_vec_strir_p_us_2(vector unsigned short *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-BE: ret <8 x i16>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-LE: ret <8 x i16>
+  for (int i = 0; i < len; i++) {
+    if (vec_strir_p(*(ptr + i))) {
+      return vec_strir(*(ptr + i));
+    }
+  }
+  return vec_strir(*(ptr));
+}
+
+vector signed short test_vec_strir_p_ss_2(vector signed short *ptr, int len) {
+  // CHECK-BE: icmp slt i32
+  // CHECK-BE: br i1
+  // CHECK-BE: for.body:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-BE: if.then:
+  // CHECK-BE: @llvm.ppc.altivec.vstrihr(<8 x i16> %{{.+}})
+  // CHECK-BE: ret <8 x i16>
+  // CHECK-LE: icmp slt i32
+  // CHECK-LE: br i1
+  // CHECK-LE: for.body:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl.p(i32 0, <8 x i16> %{{.+}})
+  // CHECK-LE: if.then:
+  // CHECK-LE: @llvm.ppc.altivec.vstrihl(<8 x i16> %{{.+}})
+  // CHECK-LE: ret <8 x i16>
+  for (int i = 0; i < len; i++) {
+    if (vec_strir_p(*(ptr + i))) {
+      return vec_strir(*(ptr + i));
+    }
+  }
+  return vec_strir(*(ptr));
+}
+
 unsigned int test_vec_extractm_uc(void) {
   // CHECK: @llvm.ppc.altivec.vextractbm(<16 x i8> %{{.+}})
   // CHECK-NEXT: ret i32

diff  --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 79cf3efbfac4..219c0d5660fc 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -501,6 +501,25 @@ let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".
               Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
                         [IntrNoMem]>;
 
+  // P10 Vector String Isolate Intrinsics.
+  def int_ppc_altivec_vstribr : GCCBuiltin<"__builtin_altivec_vstribr">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vstribl : GCCBuiltin<"__builtin_altivec_vstribl">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vstrihr : GCCBuiltin<"__builtin_altivec_vstrihr">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vstrihl : GCCBuiltin<"__builtin_altivec_vstrihl">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  // Predicate Intrinsics: The first operand specifies interpretation of CR6.
+  def int_ppc_altivec_vstribr_p : GCCBuiltin<"__builtin_altivec_vstribr_p">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vstribl_p : GCCBuiltin<"__builtin_altivec_vstribl_p">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vstrihr_p : GCCBuiltin<"__builtin_altivec_vstrihr_p">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vstrihl_p : GCCBuiltin<"__builtin_altivec_vstrihl_p">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+
   // P10 Vector Centrifuge Builtin.
   def int_ppc_altivec_vcfuged : GCCBuiltin<"__builtin_altivec_vcfuged">,
               Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],

diff  --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index d16f2e2dba71..2da9f455acd4 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -43,6 +43,7 @@
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CodeGen.h"
@@ -4677,6 +4678,45 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
     }
     break;
 
+  case ISD::INTRINSIC_WO_CHAIN: {
+    if (!PPCSubTarget->isISA3_1())
+      break;
+    unsigned Opcode = 0;
+    switch (N->getConstantOperandVal(0)) {
+    default:
+      break;
+    case Intrinsic::ppc_altivec_vstribr_p:
+      Opcode = PPC::VSTRIBR_rec;
+      break;
+    case Intrinsic::ppc_altivec_vstribl_p:
+      Opcode = PPC::VSTRIBL_rec;
+      break;
+    case Intrinsic::ppc_altivec_vstrihr_p:
+      Opcode = PPC::VSTRIHR_rec;
+      break;
+    case Intrinsic::ppc_altivec_vstrihl_p:
+      Opcode = PPC::VSTRIHL_rec;
+      break;
+    }
+    if (!Opcode)
+      break;
+
+    // Generate the appropriate vector string isolate intrinsic to match.
+    EVT VTs[] = {MVT::v16i8, MVT::Glue};
+    SDValue VecStrOp =
+        SDValue(CurDAG->getMachineNode(Opcode, dl, VTs, N->getOperand(2)), 0);
+    // Vector string isolate instructions update the EQ bit of CR6.
+    // Generate a SETBC instruction to extract the bit and place it in a GPR.
+    SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_eq, dl, MVT::i32);
+    SDValue CR6Reg = CurDAG->getRegister(PPC::CR6, MVT::i32);
+    SDValue CRBit = SDValue(
+        CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
+                               CR6Reg, SubRegIdx, VecStrOp.getValue(1)),
+        0);
+    CurDAG->SelectNodeTo(N, PPC::SETBC, MVT::i32, CRBit);
+    return;
+  }
+
   case ISD::SETCC:
   case ISD::STRICT_FSETCC:
   case ISD::STRICT_FSETCCS:

diff  --git a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td
index 114213321f35..539f4bcdc416 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td
@@ -1020,13 +1020,21 @@ let Predicates = [IsISA3_1] in {
                                                               v16i8:$VRB, 
                                                               i32:$SH))]>;
   defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$vT), (ins vrrc:$vB),
-                                 "vstribr", "$vT, $vB", IIC_VecGeneral, []>;
+                                 "vstribr", "$vT, $vB", IIC_VecGeneral,
+				 [(set v16i8:$vT,
+                                       (int_ppc_altivec_vstribr v16i8:$vB))]>;
   defm VSTRIBL : VXForm_VTB5_RCr<13, 0, (outs vrrc:$vT), (ins vrrc:$vB),
-                                 "vstribl", "$vT, $vB", IIC_VecGeneral, []>;
+                                 "vstribl", "$vT, $vB", IIC_VecGeneral,
+                                 [(set v16i8:$vT,
+                                       (int_ppc_altivec_vstribl v16i8:$vB))]>;
   defm VSTRIHR : VXForm_VTB5_RCr<13, 3, (outs vrrc:$vT), (ins vrrc:$vB),
-                                 "vstrihr", "$vT, $vB", IIC_VecGeneral, []>;
+                                 "vstrihr", "$vT, $vB", IIC_VecGeneral,
+                                 [(set v8i16:$vT,
+                                       (int_ppc_altivec_vstrihr v8i16:$vB))]>;
   defm VSTRIHL : VXForm_VTB5_RCr<13, 2, (outs vrrc:$vT), (ins vrrc:$vB),
-                                 "vstrihl", "$vT, $vB", IIC_VecGeneral, []>;
+                                 "vstrihl", "$vT, $vB", IIC_VecGeneral,
+                                 [(set v8i16:$vT,
+                                       (int_ppc_altivec_vstrihl v8i16:$vB))]>;
   def VINSW :
     VXForm_1<207, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, gprc:$rB),
              "vinsw $vD, $rB, $UIM", IIC_VecGeneral,

diff  --git a/llvm/test/CodeGen/PowerPC/p10-string-ops.ll b/llvm/test/CodeGen/PowerPC/p10-string-ops.ll
index d89045cc0200..00f136652fdb 100644
--- a/llvm/test/CodeGen/PowerPC/p10-string-ops.ll
+++ b/llvm/test/CodeGen/PowerPC/p10-string-ops.ll
@@ -2,6 +2,9 @@
 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
 ; RUN:   -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
 ; RUN:   FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
+; RUN:   FileCheck %s
 
 ; These test cases aim to test the vector string isolate builtins on Power10.
 
@@ -27,3 +30,97 @@ entry:
   %tmp = tail call <16 x i8> @llvm.ppc.altivec.vclrrb(<16 x i8> %a, i32 %n)
   ret <16 x i8> %tmp
 }
+
+declare <16 x i8> @llvm.ppc.altivec.vstribr(<16 x i8>)
+declare <16 x i8> @llvm.ppc.altivec.vstribl(<16 x i8>)
+declare <8 x i16> @llvm.ppc.altivec.vstrihr(<8 x i16>)
+declare <8 x i16> @llvm.ppc.altivec.vstrihl(<8 x i16>)
+
+declare i32 @llvm.ppc.altivec.vstribr.p(i32, <16 x i8>)
+declare i32 @llvm.ppc.altivec.vstribl.p(i32, <16 x i8>)
+declare i32 @llvm.ppc.altivec.vstrihr.p(i32, <8 x i16>)
+declare i32 @llvm.ppc.altivec.vstrihl.p(i32, <8 x i16>)
+
+define <16 x i8> @test_vstribr(<16 x i8> %a) {
+; CHECK-LABEL: test_vstribr:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstribr v2, v2
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call <16 x i8> @llvm.ppc.altivec.vstribr(<16 x i8> %a)
+  ret <16 x i8> %tmp
+}
+
+define <16 x i8> @test_vstribl(<16 x i8> %a) {
+; CHECK-LABEL: test_vstribl:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstribl v2, v2
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call <16 x i8> @llvm.ppc.altivec.vstribl(<16 x i8>%a)
+  ret <16 x i8> %tmp
+}
+
+define <8 x i16> @test_vstrihr(<8 x i16> %a) {
+; CHECK-LABEL: test_vstrihr:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstrihr v2, v2
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call <8 x i16> @llvm.ppc.altivec.vstrihr(<8 x i16> %a)
+  ret <8 x i16> %tmp
+}
+
+define <8 x i16> @test_vstrihl(<8 x i16> %a) {
+; CHECK-LABEL: test_vstrihl:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstrihl v2, v2
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call <8 x i16> @llvm.ppc.altivec.vstrihl(<8 x i16> %a)
+  ret <8 x i16> %tmp
+}
+
+define i32 @test_vstribr_p(<16 x i8> %a) {
+; CHECK-LABEL: test_vstribr_p:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstribr. v2, v2
+; CHECK-NEXT:    setbc r3, 4*cr6+eq
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call i32 @llvm.ppc.altivec.vstribr.p(i32 1, <16 x i8> %a)
+  ret i32 %tmp
+}
+
+define i32 @test_vstribl_p(<16 x i8> %a) {
+; CHECK-LABEL: test_vstribl_p:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstribl. v2, v2
+; CHECK-NEXT:    setbc r3, 4*cr6+eq
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call i32 @llvm.ppc.altivec.vstribl.p(i32 1, <16 x i8> %a)
+  ret i32 %tmp
+}
+
+define i32 @test_vstrihr_p(<8 x i16> %a) {
+; CHECK-LABEL: test_vstrihr_p:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstrihr. v2, v2
+; CHECK-NEXT:    setbc r3, 4*cr6+eq
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call i32 @llvm.ppc.altivec.vstrihr.p(i32 1, <8 x i16> %a)
+  ret i32 %tmp
+}
+
+define i32 @test_vstrihl_p(<8 x i16> %a) {
+; CHECK-LABEL: test_vstrihl_p:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vstrihl. v2, v2
+; CHECK-NEXT:    setbc r3, 4*cr6+eq
+; CHECK-NEXT:    blr
+entry:
+  %tmp = tail call i32 @llvm.ppc.altivec.vstrihl.p(i32 1, <8 x i16> %a)
+  ret i32 %tmp
+}


        


More information about the cfe-commits mailing list