Fix altivec regression caused by D115670 in Vec Const Eval

The Vector Constant Evaluator assumes that all the types of its
sub-expressions are going to be Vector APValues, which holds for most
situations.  However, in the 1 examples of Altivec C compilation of
operator ++ (not allowed for other vector types), the result is an
LValue.

Since the operator isn't supported for constant evaluation anyway, this
patch just fails-out of constant eval if we are in a situation where the
operand to the unary operator causes an LValue.
This commit is contained in:
Erich Keane 2022-01-04 09:28:22 -08:00
parent b061d86c69
commit 2edc21e856
2 changed files with 22 additions and 0 deletions

View File

@ -10434,6 +10434,15 @@ bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
if (!Evaluate(SubExprValue, Info, SubExpr))
return false;
// FIXME: This vector evaluator someday needs to be changed to be LValue
// aware/keep LValue information around, rather than dealing with just vector
// types directly. Until then, we cannot handle cases where the operand to
// these unary operators is an LValue. The only case I've been able to see
// cause this is operator++ assigning to a member expression (only valid in
// altivec compilations) in C mode, so this shouldn't limit us too much.
if (SubExprValue.isLValue())
return false;
assert(SubExprValue.getVectorLength() == VD->getNumElements() &&
"Vector length doesn't match type?");

View File

@ -45,3 +45,16 @@ void test()
int res = vGCC > vAltiVec;
vAltiVec = 0 ? vGCC : vGCC;
}
typedef struct VecMem {
vector signed vec;
} VecMem;
// The following should not assert. See qiongsiwu1's comment here:
// https://reviews.llvm.org/D115670
void test2() {
vector signed local_vec = {1, 2, 3, 4};
VecMem VM;
VM.vec = ++local_vec;
}