[PATCH] D52092: [ValueTracking] Generalize isBytewiseValue into isSplatValue

Bjorn Pettersson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 14 06:04:11 PDT 2018


bjope created this revision.

Added a generalization of isBytewiseValue that is called
isSplatValue. It takes the requested splat size (in bits)
as an additional argument.

The old isBytewiseValue remains in the code as a shortcut
for isSplatValue(V, 8).

This refactoring can be useful both when looking for non
bytewise splats, but also for out-of-tree targets that
for example implement 16-bit bytes (as they now can
override the byte size used in isBytewiseValue more easily).


Repository:
  rL LLVM

https://reviews.llvm.org/D52092

Files:
  include/llvm/Analysis/ValueTracking.h
  lib/Analysis/ValueTracking.cpp


Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -3042,46 +3042,44 @@
   return true;
 }
 
-/// If the specified value can be set by repeating the same byte in memory,
-/// return the i8 value that it is represented with.  This is
-/// true for all i8 values obviously, but is also true for i32 0, i32 -1,
-/// i16 0xF0F0, double 0.0 etc.  If the value can't be handled with a repeated
-/// byte store (e.g. i16 0x1234), return null.
-Value *llvm::isBytewiseValue(Value *V) {
-  // All byte-wide stores are splatable, even of arbitrary variables.
-  if (V->getType()->isIntegerTy(8)) return V;
+Value *llvm::isSplatValue(Value *V, unsigned SplatSizeInBits) {
+  // SplatSizeInBits sized integers are splatable
+  if (V->getType()->isIntegerTy(SplatSizeInBits)) return V;
 
   // Handle 'null' ConstantArrayZero etc.
   if (Constant *C = dyn_cast<Constant>(V))
     if (C->isNullValue())
-      return Constant::getNullValue(Type::getInt8Ty(V->getContext()));
+      return Constant::getNullValue(Type::getIntNTy(V->getContext(),
+                                                    SplatSizeInBits));
 
   // Constant float and double values can be handled as integer values if the
-  // corresponding integer value is "byteable".  An important case is 0.0.
+  // corresponding integer value is "splatable".  An important case is 0.0.
   if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
     if (CFP->getType()->isFloatTy())
       V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(V->getContext()));
     if (CFP->getType()->isDoubleTy())
       V = ConstantExpr::getBitCast(CFP, Type::getInt64Ty(V->getContext()));
     // Don't handle long double formats, which have strange constraints.
   }
 
-  // We can handle constant integers that are multiple of 8 bits.
+  // We can handle constant integers that are multiple of SplatSize bits wide.
   if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
-    if (CI->getBitWidth() % 8 == 0) {
-      assert(CI->getBitWidth() > 8 && "8 bits should be handled above!");
+    if (CI->getBitWidth() % SplatSizeInBits == 0) {
+      assert(CI->getBitWidth() > SplatSizeInBits &&
+             "SplatSize bits should be handled above!");
 
-      if (!CI->getValue().isSplat(8))
+      if (!CI->getValue().isSplat(SplatSizeInBits))
         return nullptr;
-      return ConstantInt::get(V->getContext(), CI->getValue().trunc(8));
+      return ConstantInt::get(V->getContext(),
+                              CI->getValue().trunc(SplatSizeInBits));
     }
   }
 
   // A ConstantDataArray/Vector is splatable if all its members are equal and
   // also splatable.
   if (ConstantDataSequential *CA = dyn_cast<ConstantDataSequential>(V)) {
     Value *Elt = CA->getElementAsConstant(0);
-    Value *Val = isBytewiseValue(Elt);
+    Value *Val = isSplatValue(Elt, SplatSizeInBits);
     if (!Val)
       return nullptr;
 
Index: include/llvm/Analysis/ValueTracking.h
===================================================================
--- include/llvm/Analysis/ValueTracking.h
+++ include/llvm/Analysis/ValueTracking.h
@@ -217,12 +217,18 @@
   ///   x < -0 --> false
   bool SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI);
 
-  /// If the specified value can be set by repeating the same byte in memory,
-  /// return the i8 value that it is represented with. This is true for all i8
-  /// values obviously, but is also true for i32 0, i32 -1, i16 0xF0F0, double
-  /// 0.0 etc. If the value can't be handled with a repeated byte store (e.g.
-  /// i16 0x1234), return null.
-  Value *isBytewiseValue(Value *V);
+  /// If the specified value can be set by repeating the same sequence of \p
+  /// SplatSizeInBits bits, return the i<N> value that it is represented by.
+  ///
+  /// If the value can't be represented as a repeated sequence (e.g.
+  /// i16 0x1234 with SplatSizeInBits=8), return null.
+  Value *isSplatValue(Value *V, unsigned SplatSizeInBits);
+
+  /// If the specified value is a bytewise splat value, return the value
+  /// truncated to one byte. Otherwise return null.
+  inline Value *isBytewiseValue(Value *V) {
+    return isSplatValue(V, 8);
+  }
 
   /// Given an aggregrate and an sequence of indices, see if the scalar value
   /// indexed is already around as a register, for example if it were inserted


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52092.165488.patch
Type: text/x-patch
Size: 4419 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180914/c64b23b5/attachment.bin>


More information about the llvm-commits mailing list