[PowerPC] Implement the vclz instructions for PWR8
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Thu, 5 Feb 2015 15:24:47 +0000 (15:24 +0000)
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>
Thu, 5 Feb 2015 15:24:47 +0000 (15:24 +0000)
Patch by Kit Barton.

Add the vector count leading zeros instruction for byte, halfword,
word, and doubleword sizes.  This is a fairly straightforward addition
after the changes made for vpopcnt:

 1. Add the correct definitions for the various instructions in
    PPCInstrAltivec.td
 2. Make the CTLZ operation legal on vector types when using P8Altivec
    in PPCISelLowering.cpp

Test Plan

Created new test case in test/CodeGen/PowerPC/vec_clz.ll to check the
instructions are being generated when the CTLZ operation is used in
LLVM.

Check the encoding and decoding in test/MC/PowerPC/ppc_encoding_vmx.s
and test/Disassembler/PowerPC/ppc_encoding_vmx.txt respectively.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228301 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCInstrAltivec.td
test/CodeGen/PowerPC/vec_clz.ll [new file with mode: 0644]
test/MC/Disassembler/PowerPC/ppc64-encoding-vmx.txt
test/MC/PowerPC/ppc64-encoding-vmx.s

index dd3362ff35337ed2f84bd73d2e1211142dfbe846..b98c9e1b0674fca28bf3d0d163a2430df94b7dff 100644 (file)
@@ -401,11 +401,15 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
       setOperationAction(ISD::ADD , VT, Legal);
       setOperationAction(ISD::SUB , VT, Legal);
 
-      // Vector popcnt instructions introduced in P8
-      if (Subtarget.hasP8Altivec()) 
+      // Vector instructions introduced in P8
+      if (Subtarget.hasP8Altivec()) {
         setOperationAction(ISD::CTPOP, VT, Legal);
-      else 
+        setOperationAction(ISD::CTLZ, VT, Legal);
+      }
+      else {
         setOperationAction(ISD::CTPOP, VT, Expand);
+        setOperationAction(ISD::CTLZ, VT, Expand);
+      }
 
       // We promote all shuffles to v16i8.
       setOperationAction(ISD::VECTOR_SHUFFLE, VT, Promote);
@@ -461,7 +465,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
       setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Expand);
       setOperationAction(ISD::FPOW, VT, Expand);
       setOperationAction(ISD::BSWAP, VT, Expand);
-      setOperationAction(ISD::CTLZ, VT, Expand);
       setOperationAction(ISD::CTLZ_ZERO_UNDEF, VT, Expand);
       setOperationAction(ISD::CTTZ, VT, Expand);
       setOperationAction(ISD::CTTZ_ZERO_UNDEF, VT, Expand);
index 5641b536569851698cd698e950a504cdcc4aefd2..9379bad7317b00777aceeb7329a269371c501722 100644 (file)
@@ -940,6 +940,21 @@ def : Pat<(v4f32 (fnearbyint v4f32:$vA)),
 
 def HasP8Altivec : Predicate<"PPCSubTarget->hasP8Altivec()">;
 let Predicates = [HasP8Altivec] in {
+
+// Count Leading Zeros
+def VCLZB : VXForm_2<1794, (outs vrrc:$vD), (ins vrrc:$vB),
+                     "vclzb $vD, $vB", IIC_VecGeneral,
+                     [(set v16i8:$vD, (ctlz v16i8:$vB))]>;
+def VCLZH : VXForm_2<1858, (outs vrrc:$vD), (ins vrrc:$vB),
+                     "vclzh $vD, $vB", IIC_VecGeneral,
+                     [(set v8i16:$vD, (ctlz v8i16:$vB))]>;
+def VCLZW : VXForm_2<1922, (outs vrrc:$vD), (ins vrrc:$vB),
+                     "vclzw $vD, $vB", IIC_VecGeneral,
+                     [(set v4i32:$vD, (ctlz v4i32:$vB))]>;
+def VCLZD : VXForm_2<1986, (outs vrrc:$vD), (ins vrrc:$vB),
+                     "vclzd $vD, $vB", IIC_VecGeneral,
+                     [(set v2i64:$vD, (ctlz v2i64:$vB))]>;
+
 // Population Count
 def VPOPCNTB : VXForm_2<1795, (outs vrrc:$vD), (ins vrrc:$vB),
                         "vpopcntb $vD, $vB", IIC_VecGeneral,
diff --git a/test/CodeGen/PowerPC/vec_clz.ll b/test/CodeGen/PowerPC/vec_clz.ll
new file mode 100644 (file)
index 0000000..01cdecd
--- /dev/null
@@ -0,0 +1,40 @@
+; Check the vctlz* instructions that were added in P8
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s
+
+declare <16 x i8> @llvm.ctlz.v16i8(<16 x i8>) nounwind readnone
+declare <8 x i16> @llvm.ctlz.v8i16(<8 x i16>) nounwind readnone
+declare <4 x i32> @llvm.ctlz.v4i32(<4 x i32>) nounwind readnone
+declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>) nounwind readnone
+
+define <16 x i8> @test_v16i8(<16 x i8> %x) nounwind readnone {
+       %vcnt = tail call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %x)
+       ret <16 x i8> %vcnt
+; CHECK: @test_v16i8
+; CHECK: vclzb 2, 2
+; CHECK: blr
+}
+
+define <8 x i16> @test_v8i16(<8 x i16> %x) nounwind readnone {
+       %vcnt = tail call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %x)
+       ret <8 x i16> %vcnt
+; CHECK: @test_v8i16
+; CHECK: vclzh 2, 2
+; CHECK: blr
+}
+
+define <4 x i32> @test_v4i32(<4 x i32> %x) nounwind readnone {
+       %vcnt = tail call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %x)
+       ret <4 x i32> %vcnt
+; CHECK: @test_v4i32
+; CHECK: vclzw 2, 2
+; CHECK: blr
+}
+
+define <2 x i64> @test_v2i64(<2 x i64> %x) nounwind readnone {
+       %vcnt = tail call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %x)
+       ret <2 x i64> %vcnt
+; CHECK: @test_v2i64
+; CHECK: vclzd 2, 2
+; CHECK: blr
+}
index 72c5e64ab48aba3969fb84df9ab3f979ff3fac92..4f12a6cd16602903663f7bdd6a2c003018d861e6 100644 (file)
 # CHECK: vrsqrtefp 2, 3                  
 0x10 0x40 0x19 0x4a
 
+# CHECK: vclzb 2, 3
+0x10 0x40 0x1f 0x02
+
+# CHECK: vclzh 2, 3
+0x10 0x40 0x1f 0x42
+
+# CHECK: vclzw 2, 3
+0x10 0x40 0x1f 0x82
+
+# CHECK: vclzd 2, 3
+0x10 0x40 0x1f 0xc2
+
 # CHECK: vpopcntb 2, 3
 0x10 0x40 0x1f 0x03
 
index 3247d407f5e9bb6e11c6a990eb939bd3a8e7f703..09e5ecc5e77df264b739e2830b645019c982f180 100644 (file)
 # CHECK-LE: vrsqrtefp 2, 3                  # encoding: [0x4a,0x19,0x40,0x10]
             vrsqrtefp 2, 3
 
+# Vector count leading zero instructions
+# CHECK-BE: vclzb 2, 3                      # encoding: [0x10,0x40,0x1f,0x02]
+# CHECK-LE: vclzb 2, 3                      # encoding: [0x02,0x1f,0x40,0x10]
+            vclzb 2, 3
+
+# CHECK-BE: vclzh 2, 3                      # encoding: [0x10,0x40,0x1f,0x42]
+# CHECK-LE: vclzh 2, 3                      # encoding: [0x42,0x1f,0x40,0x10]
+            vclzh 2, 3
+
+# CHECK-BE: vclzw 2, 3                      # encoding: [0x10,0x40,0x1f,0x82]
+# CHECK-LE: vclzw 2, 3                      # encoding: [0x82,0x1f,0x40,0x10]
+            vclzw 2, 3
+
+# CHECK-BE: vclzd 2, 3                      # encoding: [0x10,0x40,0x1f,0xc2]
+# CHECK-LE: vclzd 2, 3                      # encoding: [0xc2,0x1f,0x40,0x10]
+            vclzd 2, 3                      
+
 # Vector population count instructions
 # CHECK-BE: vpopcntb 2, 3                   # encoding: [0x10,0x40,0x1f,0x03]
 # CHECK-LE: vpopcntb 2, 3                   # encoding: [0x03,0x1f,0x40,0x10]