[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);
+ 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())));
----------------
zygoloid wrote:
```suggestion
llvm::APInt Elt = SValInt.extractBits(FloatEltSize, (BigEndian ? NElts - i - 1 : i) * EltSize));
Elts.push_back(APValue(APSInt(std::move(Elt), !EltTy->isSignedIntegerType())));
```
As above, but also `std::move` the `APInt` into the `APSInt` to avoid another heap allocation if the element size is > 64 bits.
https://github.com/llvm/llvm-project/pull/66894
More information about the cfe-commits
mailing list