[llvm] ValueTracking: introduce llvm::isLanewiseOperation (PR #112011)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 12 07:05:38 PDT 2024


================
@@ -6947,6 +6947,81 @@ bool llvm::onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V) {
       V, /* AllowLifetime */ true, /* AllowDroppable */ true);
 }
 
+bool llvm::isLanewiseOperation(const Instruction *I) {
+  if (auto *II = dyn_cast<IntrinsicInst>(I)) {
+    switch (II->getIntrinsicID()) {
+    // TODO: expand this list.
+    case Intrinsic::abs:
+    case Intrinsic::smax:
+    case Intrinsic::smin:
+    case Intrinsic::umax:
+    case Intrinsic::umin:
+    case Intrinsic::sqrt:
+    case Intrinsic::powi:
+    case Intrinsic::sin:
+    case Intrinsic::cos:
+    case Intrinsic::tan:
+    case Intrinsic::asin:
+    case Intrinsic::acos:
+    case Intrinsic::atan:
+    case Intrinsic::atan2:
+    case Intrinsic::sinh:
+    case Intrinsic::cosh:
+    case Intrinsic::tanh:
+    case Intrinsic::pow:
+    case Intrinsic::exp:
+    case Intrinsic::exp2:
+    case Intrinsic::exp10:
+    case Intrinsic::ldexp:
+    case Intrinsic::frexp:
+    case Intrinsic::log:
+    case Intrinsic::log10:
+    case Intrinsic::log2:
+    case Intrinsic::fma:
+    case Intrinsic::fabs:
+    case Intrinsic::minimum:
+    case Intrinsic::maximum:
+    case Intrinsic::minimumnum:
+    case Intrinsic::maximumnum:
+    case Intrinsic::copysign:
+    case Intrinsic::floor:
+    case Intrinsic::ceil:
+    case Intrinsic::trunc:
+    case Intrinsic::rint:
+    case Intrinsic::nearbyint:
+    case Intrinsic::round:
+    case Intrinsic::roundeven:
+    case Intrinsic::lround:
+    case Intrinsic::llround:
+    case Intrinsic::lrint:
+    case Intrinsic::llrint:
+    case Intrinsic::bitreverse:
+    case Intrinsic::bswap:
+    case Intrinsic::ctpop:
+    case Intrinsic::ctlz:
+    case Intrinsic::cttz:
+    case Intrinsic::fshl:
+    case Intrinsic::fshr:
+    case Intrinsic::usub_sat:
+    case Intrinsic::uadd_sat:
+    case Intrinsic::ushl_sat:
+    case Intrinsic::ssub_sat:
+    case Intrinsic::sadd_sat:
+    case Intrinsic::sshl_sat:
+    case Intrinsic::canonicalize:
+    case Intrinsic::fmuladd:
+    case Intrinsic::fptoui_sat:
+    case Intrinsic::fptosi_sat:
+      return true;
+    default:
+      return false;
+    }
+  }
+  auto *Shuffle = dyn_cast<ShuffleVectorInst>(I);
+  return (!Shuffle || Shuffle->isIdentity() || Shuffle->isSelect()) &&
----------------
artagnon wrote:

There is a usecase for `isSelect`. Will strip `isIdentity`.

```llvm
define <4 x i8> @select_icmp_shufflevector_select(<4 x i8> %x, <4 x i8> %y, <4 x i8> %z) {
; CHECK-LABEL: define <4 x i8> @select_icmp_shufflevector_select(
; CHECK-SAME: <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i8> [[Z:%.*]]) {
; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <4 x i8> [[Y]], <i8 2, i8 2, i8 2, i8 2>
; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i8> [[Z]], <4 x i8> <i8 poison, i8 2, i8 poison, i8 2>, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
; CHECK-NEXT:    [[RETVAL:%.*]] = select <4 x i1> [[CMP]], <4 x i8> [[SHUFFLE]], <4 x i8> [[X]]
; CHECK-NEXT:    ret <4 x i8> [[RETVAL]]
;
  %cmp = icmp eq <4 x i8> %y, <i8 2, i8 2, i8 2, i8 2>
  %shuffle = shufflevector <4 x i8> %y, <4 x i8> %z, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
  %retval = select <4 x i1> %cmp, <4 x i8> %shuffle, <4 x i8> %x
  ret <4 x i8> %retval
}
```

https://github.com/llvm/llvm-project/pull/112011


More information about the llvm-commits mailing list