Fix a failing assertion with vector type initialization

When constant evaluating the initializer for an object of vector type,
we would call APInt::trunc() but truncate to the same bit-width the
object already had, which would cause an assertion. Instead, use
APInt::truncOrSelf() so that we no longer assert in this situation.

Fix #50216
This commit is contained in:
Aaron Ballman 2022-05-04 13:22:30 -04:00
parent 14f257620c
commit 859d923948
3 changed files with 14 additions and 2 deletions

View File

@ -132,6 +132,10 @@ Bug Fixes
argument to a generic selection expression has side effects in the case where
the expression is result dependent. This fixes
`Issue 50227 <https://github.com/llvm/llvm-project/issues/50227>`_.
- Fixed an assertion when constant evaluating an initializer for a GCC/Clang
floating-point vector type when the width of the initialization is exactly
the same as the elements of the vector being initialized.
Fixes `Issue 50216 <https://github.com/llvm/llvm-project/issues/50216>`_.
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -10353,9 +10353,9 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) {
for (unsigned i = 0; i < NElts; i++) {
llvm::APInt Elt;
if (BigEndian)
Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
Elt = SValInt.rotl(i*EltSize+FloatEltSize).truncOrSelf(FloatEltSize);
else
Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
Elt = SValInt.rotr(i*EltSize).truncOrSelf(FloatEltSize);
Elts.push_back(APValue(APFloat(Sem, Elt)));
}
} else if (EltTy->isIntegerType()) {

View File

@ -42,3 +42,11 @@ void test3(void) {
longlong2 arr1[2] = { test3_helper(), test3_helper() };
short4 arr2[2] = { test3_helper(), test3_helper() }; // expected-error 2 {{initializing 'short4' (vector of 4 'short' values) with an expression of incompatible type 'short8' (vector of 8 'short' values)}}
}
// GH50216
// These would previously crash when constant evaluating the initializers.
typedef double float64x1_t __attribute__((vector_size(8)));
float64x1_t arg1 = (float64x1_t)0x3fedf9d4343c7c80; // okay
typedef float float32x1_t __attribute__((vector_size(4)));
float32x1_t arg2 = (float32x1_t)0x3fedf9d4; // okay