[clang] [clang] Implement constexpr bit_cast for vectors (PR #66894)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 5 04:32:16 PDT 2023
================
@@ -10517,41 +10598,19 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) {
return Success(Elts, E);
}
case CK_BitCast: {
- // Evaluate the operand into an APInt we can extract from.
- llvm::APInt SValInt;
- if (!EvalAndBitcastToAPInt(Info, SE, SValInt))
+ APValue SVal;
+ if (!Evaluate(SVal, Info, SE))
return false;
- // Extract the elements
- QualType EltTy = VTy->getElementType();
- unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
- bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
- SmallVector<APValue, 4> Elts;
- if (EltTy->isRealFloatingType()) {
- const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
- unsigned FloatEltSize = EltSize;
- if (&Sem == &APFloat::x87DoubleExtended())
- FloatEltSize = 80;
- for (unsigned i = 0; i < NElts; i++) {
- llvm::APInt Elt;
- if (BigEndian)
- Elt = SValInt.rotl(i * EltSize + FloatEltSize).trunc(FloatEltSize);
- else
- Elt = SValInt.rotr(i * EltSize).trunc(FloatEltSize);
- Elts.push_back(APValue(APFloat(Sem, Elt)));
- }
- } else if (EltTy->isIntegerType()) {
- for (unsigned i = 0; i < NElts; i++) {
- llvm::APInt Elt;
- if (BigEndian)
- Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
- else
- Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
- Elts.push_back(APValue(APSInt(Elt, !EltTy->isSignedIntegerType())));
- }
- } else {
+
+ if (!SVal.isInt() && !SVal.isFloat() && !SVal.isVector())
+ // Give up if the input isn't an int, float, or vector. For example, we
+ // reject "(v4i16)(intptr_t)&a".
----------------
DaMatrix wrote:
Well, `handleRValueToRValueBitCast` allows structs and arrays... I'll just improve the diagnostic message produced here instead.
https://github.com/llvm/llvm-project/pull/66894
More information about the cfe-commits
mailing list