[llvm] [VPlan] Introduce VPlanConstantFolder (PR #125365)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sat May 3 05:15:52 PDT 2025
================
@@ -0,0 +1,157 @@
+//===- VPlanConstantFolder.h - ConstantFolder for VPlan -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANCONSTANTFOLDER_H
+#define LLVM_TRANSFORMS_VECTORIZE_VPLANCONSTANTFOLDER_H
+
+#include "VPlan.h"
+#include "VPlanValue.h"
+#include "llvm/Analysis/TargetFolder.h"
+
+namespace llvm {
+class VPConstantFolder {
+ TargetFolder Folder;
+ VPTypeAnalysis TypeInfo;
+
+ Constant *getIRConstant(VPValue *V) const {
+ if (!V->isLiveIn())
+ return nullptr;
+ return dyn_cast_if_present<Constant>(V->getLiveInIRValue());
+ }
+
+ Value *foldBinOp(Instruction::BinaryOps Opcode, VPValue *LHS,
+ VPValue *RHS) const {
+ auto *LC = getIRConstant(LHS);
+ auto *RC = getIRConstant(RHS);
+ if (LC && RC)
+ return Folder.FoldBinOp(Opcode, LC, RC);
+ return nullptr;
+ }
+
+ Value *foldNot(VPValue *Op) const {
+ auto *C = getIRConstant(Op);
+ if (C)
+ return Folder.FoldBinOp(Instruction::BinaryOps::Xor, C,
+ Constant::getAllOnesValue(C->getType()));
+ return nullptr;
+ }
+
+ Value *foldLogicalAnd(VPValue *LHS, VPValue *RHS) const {
+ auto *LC = getIRConstant(LHS);
+ auto *RC = getIRConstant(RHS);
+ if (LC && RC)
+ return Folder.FoldSelect(LC, RC,
+ ConstantInt::getNullValue(RC->getType()));
+ return nullptr;
+ }
+
+ Value *foldSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal) const {
+ auto *CC = getIRConstant(Cond);
+ auto *TV = getIRConstant(TrueVal);
+ auto *FV = getIRConstant(FalseVal);
+ if (CC && TV && FV)
+ return Folder.FoldSelect(CC, TV, FV);
+ return nullptr;
+ }
+
+ Value *foldCmp(CmpInst::Predicate Pred, VPValue *LHS, VPValue *RHS) const {
+ auto *LC = getIRConstant(LHS);
+ auto *RC = getIRConstant(RHS);
+ if (LC && RC)
+ return Folder.FoldCmp(Pred, LC, RC);
+ return nullptr;
+ }
+
+ Value *foldGEP(Type *Ty, VPValue *Base, ArrayRef<VPValue *> Offsets,
+ GEPNoWrapFlags NW) const {
+ auto *BC = getIRConstant(Base);
+ if (!BC)
+ return nullptr;
+ SmallVector<Value *> IdxList;
+ for (auto *O : Offsets) {
+ if (auto *OffsetV = getIRConstant(O))
+ IdxList.emplace_back(OffsetV);
+ else
+ return nullptr;
+ }
+ return Folder.FoldGEP(Ty, BC, IdxList, NW);
+ }
+
+ Value *foldInsertElement(VPValue *Vec, VPValue *NewElt, VPValue *Idx) const {
+ auto *VC = getIRConstant(Vec);
+ auto *EC = getIRConstant(NewElt);
+ auto *IC = getIRConstant(Idx);
+ if (VC && EC && IC)
+ Folder.FoldInsertElement(VC, EC, IC);
+ return nullptr;
+ }
+
+ Value *foldExtractElement(VPValue *Vec, VPValue *Idx) const {
+ auto *VC = getIRConstant(Vec);
+ auto *IC = getIRConstant(Idx);
+ if (VC && IC)
+ Folder.FoldExtractElement(VC, IC);
+ return nullptr;
+ }
+
+ Value *foldCast(Instruction::CastOps Opcode, VPValue *Op,
+ Type *DestTy) const {
+ auto *C = getIRConstant(Op);
+ if (C)
+ return Folder.FoldCast(Opcode, C, DestTy);
+ return nullptr;
+ }
+
+public:
+ VPConstantFolder(const DataLayout &DL, const VPTypeAnalysis &TypeInfo)
+ : Folder(DL), TypeInfo(TypeInfo) {}
+
+ Value *tryToConstantFold(VPRecipeBase &R, unsigned Opcode,
+ ArrayRef<VPValue *> Ops) {
----------------
fhahn wrote:
Would it simplify things to check front check if any op is not a live in and do getIRConstant in a single place?
https://github.com/llvm/llvm-project/pull/125365
More information about the llvm-commits
mailing list