[clang] [clang] Implement constexpr bit_cast for vectors (PR #66894)
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 27 17:34:16 PDT 2023
================
@@ -2732,6 +2732,92 @@ static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E,
return true;
}
+static bool BitcastAPIntToVector(EvalInfo &Info, const VectorType *VTy,
+ const llvm::APInt &SValInt,
+ SmallVectorImpl<APValue> &Elts) {
+ QualType EltTy = VTy->getElementType();
+ unsigned NElts = VTy->getNumElements();
+ unsigned EltSize =
+ VTy->isExtVectorBoolType() ? 1 : Info.Ctx.getTypeSize(EltTy);
+
+ if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
+ // The vector's size in bits is not a multiple of the target's byte size,
+ // so its layout is unspecified. For now, we'll simply treat these cases as
+ // unsupported (this should only be possible with OpenCL bool vectors whose
+ // element count isn't a multiple of the byte size).
+ return false;
+ }
+
+ Elts.reserve(NElts);
+ bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
+ 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);
----------------
zygoloid wrote:
```suggestion
llvm::APInt Elt = SValInt.extractBits(FloatEltSize, BigEndian ? (NElts - i) * EltSize - FloatEltSize : i * EltSize);
```
Extracting the bits in one go will avoid a heap allocation if the vector is larger than 64 bits but its elements are not.
https://github.com/llvm/llvm-project/pull/66894
More information about the cfe-commits
mailing list