Lax vector conversions was behaving incorrectly for implicit casts
between scalable and fixed-length vector types. For example, this:
#include <arm_sve.h>
#define N __ARM_FEATURE_SVE_BITS
#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
typedef svfloat32_t fixed_float32_t FIXED_ATTR;
void allowed_depending() {
fixed_float32_t fs32;
svfloat64_t s64;
fs32 = s64;
}... would fail because the vectors have differing lane sizes. This patch
implements the correct behaviour for
-flax-vector-conversions={none,all,integer}. Specifically:
- -flax-vector-conversions=none prevents all lax vector conversions between scalable and fixed-sized vectors.
- -flax-vector-conversions=integer allows lax vector conversions between scalable and fixed-size vectors whose element types are integers.
- -flax-vector-conversions=all allows all lax vector conversions between scalable and fixed-size vectors (including those with floating point element types).
The implicit conversions are implemented as bitcasts.
May I ask to avoid this triple if statement? Given that BT is not used after being defined, I think the following form would be easier to understand:
if (!FirstType->getAs<BuiltinType>()) return false; const auto *VT = SecondType->getAs<VectorType>(); if (VT && VT->getVectorKind() == VectorType::SveFixedLengthDataVector) { /// ... return ... } return false;May I ask you to give meaningful names to the variables? BT and VT are quite cryptic to me.
Moreover.. are BT and VT really needed? You are asserting FirstType->isSizelessBuiltinType() && SecondType->isVectorType() ... the getAs calls should not fail, no? given that the lambda is local to this method, I wouldn't bother making it work for the generic case.