[llvm] [Scalarizer][DirectX] support structs return types (PR #111569)

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 12:30:59 PDT 2024


================
@@ -667,14 +686,26 @@ bool ScalarizerVisitor::splitBinary(Instruction &I, const Splitter &Split) {
 bool ScalarizerVisitor::isTriviallyScalarizable(Intrinsic::ID ID) {
   if (isTriviallyVectorizable(ID))
     return true;
+  // TODO: Move frexp to isTriviallyVectorizable.
+  // https://github.com/llvm/llvm-project/issues/112408
+  switch (ID) {
+  case Intrinsic::frexp:
+    return true;
+  }
   return Intrinsic::isTargetIntrinsic(ID) &&
          TTI->isTargetIntrinsicTriviallyScalarizable(ID);
 }
 
 /// If a call to a vector typed intrinsic function, split into a scalar call per
 /// element if possible for the intrinsic.
 bool ScalarizerVisitor::splitCall(CallInst &CI) {
-  std::optional<VectorSplit> VS = getVectorSplit(CI.getType());
+  Type *CallType = CI.getType();
+  bool AreAllMatchingVectors = isStructOfMatchingFixedVectors(CallType);
+  std::optional<VectorSplit> VS;
+  if (AreAllMatchingVectors)
+    VS = getVectorSplit(CallType->getContainedType(0));
----------------
farzonl wrote:

I think you are confusing a few things.  First the overload  type is not based on the return type. The `isVectorIntrinsicWithOverloadTypeAtArg` has a pass through behavior of  `OpdIdx == -1`  All return indices will be true. Second We build up the return in lines 733 to 748.  `lvm.frexp.v2f64.v2i32` becomes two `lvm.frexp.f64.i32`.

Third the behavior of `isVectorIntrinsicWithOverloadTypeAtArg` isn't relevant for struct return types. The scope of this change is not intended to impact any argument overload cases. 

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


More information about the llvm-commits mailing list