[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

Pol M via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 1 03:26:00 PDT 2024


Pol Marcet =?utf-8?q?Sardà?= <polmarcetsarda at gmail.com>,
Pol Marcet =?utf-8?q?Sardà?= <polmarcetsarda at gmail.com>,
Pol Marcet =?utf-8?q?Sardà?= <polmarcetsarda at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/76615 at github.com>


================
@@ -10895,6 +10899,132 @@ bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
   return Success(APValue(ResultElements.data(), ResultElements.size()), E);
 }
 
+static bool EvaluateVectorOrLValue(APValue &Result, EvalInfo &Info,
+                                   const Expr *E, const QualType &Type) {
+  if (!Evaluate(Result, Info, E))
+    return false;
+
+  if (Result.isLValue()) {
+    // Source of the data is an lvalue; Manually handle the lvalue as if
+    // it was an rvalue to get the current APValue.
+    LValue LValueFound;
+    LValueFound.setFrom(Info.Ctx, Result);
+    if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result))
+      return false;
+  }
+
+  return Result.isVector();
+}
+
+static bool handleVectorConversion(EvalInfo &Info, const FPOptions FPO,
+                                   const Expr *E, QualType SourceTy,
+                                   QualType DestTy, APValue const &Original,
+                                   APValue &Result) {
+  if (SourceTy->isIntegerType()) {
+    if (DestTy->isRealFloatingType()) {
+      Result = APValue(APFloat(0.0));
+      return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(),
+                                  DestTy, Result.getFloat());
+    }
+    if (DestTy->isIntegerType()) {
+      Result = APValue(
+          HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt()));
+      return true;
+    }
+  } else if (SourceTy->isRealFloatingType()) {
+    if (DestTy->isRealFloatingType()) {
+      Result = Original;
+      return HandleFloatToFloatCast(Info, E, SourceTy, DestTy,
+                                    Result.getFloat());
+    }
+    if (DestTy->isIntegerType()) {
+      Result = APValue(APSInt());
+      return HandleFloatToIntCast(Info, E, SourceTy, Original.getFloat(),
+                                  DestTy, Result.getInt());
+    }
+  }
+  return false;
+}
+
+bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
+  APValue Source;
+  QualType SourceVecType = E->getSrcExpr()->getType();
+  if (!EvaluateVectorOrLValue(Source, Info, E->getSrcExpr(), SourceVecType))
+    return false;
+
+  QualType DestTy = E->getType()->castAs<VectorType>()->getElementType();
+  QualType SourceTy = SourceVecType->castAs<VectorType>()->getElementType();
+
+  const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+
+  auto SourceLen = Source.getVectorLength();
+  SmallVector<APValue, 4> ResultElements;
----------------
Destroyerrrocket wrote:

304 bytes is definitely inside what I'd be slightly worried to allocate without thinking into the stack, but having looked at it I think it's going to be fine. We're not the only case of smallVectors with APValues, and I'm sure that if it ever becomes a problem the default stack size can be modified (or the code can be refactored, I'm sure that if that ever happens it's not going to be "just" the fault of a smallvector of APValues). I thank you for pointing it out, as I simply did not check!

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


More information about the cfe-commits mailing list