[llvm] [VPlan] Fold unary intrinsics with live-in operands (PR #202944)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 04:51:22 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-llvm-analysis

Author: Ramkumar Ramachandra (artagnon)

<details>
<summary>Changes</summary>

The InstSimplifyFolder is not strictly more powerful than the TargetFolder for intrinsics, and we have hence added a fallback.

---
Full diff: https://github.com/llvm/llvm-project/pull/202944.diff


3 Files Affected:

- (modified) llvm/include/llvm/Analysis/InstSimplifyFolder.h (+4) 
- (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+12-6) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/funclet.ll (+1-2) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
index a8dff839de214..ce9a819255899 100644
--- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h
+++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
@@ -123,12 +123,16 @@ class LLVM_ABI InstSimplifyFolder final : public IRBuilderFolder {
   Value *
   FoldUnaryIntrinsic(Intrinsic::ID ID, Value *Op, Type *Ty,
                      FastMathFlags FMF = FastMathFlags()) const override {
+    if (Value *V = ConstFolder.FoldUnaryIntrinsic(ID, Op, Ty, FMF))
+      return V;
     return simplifyUnaryIntrinsic(ID, Op, FMF, SQ);
   }
 
   Value *
   FoldBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Type *Ty,
                       FastMathFlags FMF = FastMathFlags()) const override {
+    if (Value *V = ConstFolder.FoldBinaryIntrinsic(ID, LHS, RHS, Ty, FMF))
+      return V;
     return simplifyBinaryIntrinsic(ID, Ty, LHS, RHS, FMF, SQ);
   }
 
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index cc19c1c1faa2d..6ce27d50c4400 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1241,14 +1241,14 @@ static void recursivelyDeleteDeadRecipes(VPValue *V) {
 /// an intrinsic ID.
 static std::optional<std::pair<bool, unsigned>>
 getOpcodeOrIntrinsicID(const VPSingleDefRecipe *R) {
+  Intrinsic::ID IID = vputils::getIntrinsicID(R);
+  if (IID != Intrinsic::not_intrinsic)
+    return std::make_pair(true, IID);
   return TypeSwitch<const VPSingleDefRecipe *,
                     std::optional<std::pair<bool, unsigned>>>(R)
       .Case<VPInstruction, VPWidenRecipe, VPWidenCastRecipe, VPWidenGEPRecipe,
             VPReplicateRecipe>(
           [](auto *I) { return std::make_pair(false, I->getOpcode()); })
-      .Case([](const VPWidenIntrinsicRecipe *I) {
-        return std::make_pair(true, I->getVectorIntrinsicID());
-      })
       .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
           [](auto *I) {
             // For recipes that do not directly map to LLVM IR instructions,
@@ -1286,10 +1286,16 @@ static VPIRValue *tryToFoldLiveIns(VPSingleDefRecipe &R,
   auto FoldToIRValue = [&]() -> Value * {
     InstSimplifyFolder Folder(DL);
     if (OpcodeOrIID->first) {
-      if (R.getNumOperands() != 2)
-        return nullptr;
       unsigned ID = OpcodeOrIID->second;
-      return Folder.FoldBinaryIntrinsic(ID, Ops[0], Ops[1], R.getScalarType());
+      if (R.getNumOperands() == 2)
+        return Folder.FoldBinaryIntrinsic(
+            ID, Ops[0], Ops[1], R.getScalarType(),
+            cast<VPRecipeWithIRFlags>(R).getFastMathFlagsOrNone());
+      if (R.getNumOperands() == 1)
+        return Folder.FoldUnaryIntrinsic(
+            ID, Ops[0], R.getScalarType(),
+            cast<VPRecipeWithIRFlags>(R).getFastMathFlagsOrNone());
+      return nullptr;
     }
     unsigned Opcode = OpcodeOrIID->second;
     if (Instruction::isBinaryOp(Opcode))
diff --git a/llvm/test/Transforms/LoopVectorize/X86/funclet.ll b/llvm/test/Transforms/LoopVectorize/X86/funclet.ll
index 58812b5e2309d..fa858d6d6fbbc 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/funclet.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/funclet.ll
@@ -26,10 +26,9 @@ define void @test1() #0 personality ptr @__CxxFrameHandler3 {
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1024
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[TRY_CONT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
 ; CHECK:       [[TRY_CONT]]:
-; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <16 x double> [[TMP2]], i64 15
 ; CHECK-NEXT:    br label %[[EXIT:.*]]
 ; CHECK:       [[EXIT]]:
-; CHECK-NEXT:    store double [[TMP4]], ptr @sink, align 8
+; CHECK-NEXT:    store double 1.000000e+00, ptr @sink, align 8
 ; CHECK-NEXT:    catchret from [[TMP1]] to label %[[TRY_CONT1:.*]]
 ; CHECK:       [[TRY_CONT1]]:
 ; CHECK-NEXT:    ret void

``````````

</details>


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


More information about the llvm-commits mailing list