Skip to content

Commit 96509bb

Browse files
authored
[Matrix] Preserve signedness when extending matrix index expression. (#103044)
As per [1] the indices for a matrix element access operator shall have integral or unscoped enumeration types and be non-negative. At the moment, the index expression is converted to SizeType irrespective of the signedness of the index expression. This causes implicit sign conversion warnings if any of the indices is signed. As per the spec, using signed types as indices is allowed and should not cause any warnings. If the index expression is signed, extend to SignedSizeType to avoid the warning. [1] https://clang.llvm.org/docs/MatrixTypes.html#matrix-type-element-access-operator PR: #103044
1 parent b02b5b7 commit 96509bb

File tree

5 files changed

+19
-11
lines changed

5 files changed

+19
-11
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4392,13 +4392,24 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
43924392
return LV;
43934393
}
43944394

4395+
llvm::Value *CodeGenFunction::EmitMatrixIndexExpr(const Expr *E) {
4396+
llvm::Value *Idx = EmitScalarExpr(E);
4397+
if (Idx->getType() == IntPtrTy)
4398+
return Idx;
4399+
bool IsSigned = E->getType()->isSignedIntegerOrEnumerationType();
4400+
return Builder.CreateIntCast(Idx, IntPtrTy, IsSigned);
4401+
}
4402+
43954403
LValue CodeGenFunction::EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E) {
43964404
assert(
43974405
!E->isIncomplete() &&
43984406
"incomplete matrix subscript expressions should be rejected during Sema");
43994407
LValue Base = EmitLValue(E->getBase());
4400-
llvm::Value *RowIdx = EmitScalarExpr(E->getRowIdx());
4401-
llvm::Value *ColIdx = EmitScalarExpr(E->getColumnIdx());
4408+
4409+
// Extend or truncate the index type to 32 or 64-bits if needed.
4410+
llvm::Value *RowIdx = EmitMatrixIndexExpr(E->getRowIdx());
4411+
llvm::Value *ColIdx = EmitMatrixIndexExpr(E->getColumnIdx());
4412+
44024413
llvm::Value *NumRows = Builder.getIntN(
44034414
RowIdx->getType()->getScalarSizeInBits(),
44044415
E->getBase()->getType()->castAs<ConstantMatrixType>()->getNumRows());

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,8 +2007,8 @@ Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
20072007

20082008
// Handle the vector case. The base must be a vector, the index must be an
20092009
// integer value.
2010-
Value *RowIdx = Visit(E->getRowIdx());
2011-
Value *ColumnIdx = Visit(E->getColumnIdx());
2010+
Value *RowIdx = CGF.EmitMatrixIndexExpr(E->getRowIdx());
2011+
Value *ColumnIdx = CGF.EmitMatrixIndexExpr(E->getColumnIdx());
20122012

20132013
const auto *MatrixTy = E->getBase()->getType()->castAs<ConstantMatrixType>();
20142014
unsigned NumRows = MatrixTy->getNumRows();

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4280,6 +4280,7 @@ class CodeGenFunction : public CodeGenTypeCache {
42804280
LValue EmitUnaryOpLValue(const UnaryOperator *E);
42814281
LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
42824282
bool Accessed = false);
4283+
llvm::Value *EmitMatrixIndexExpr(const Expr *E);
42834284
LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E);
42844285
LValue EmitArraySectionExpr(const ArraySectionExpr *E,
42854286
bool IsLowerBound = true);

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5033,8 +5033,7 @@ ExprResult Sema::CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
50335033
}
50345034
}
50355035

5036-
ExprResult ConvExpr =
5037-
tryConvertExprToType(IndexExpr, Context.getSizeType());
5036+
ExprResult ConvExpr = IndexExpr;
50385037
assert(!ConvExpr.isInvalid() &&
50395038
"should be able to convert any integer type to size type");
50405039
return ConvExpr.get();

clang/test/SemaCXX/matrix-index-operator-sign-conversion.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,16 @@
22

33
template <typename T, int R, int C> using m __attribute__((__matrix_type__(R,C))) = T;
44

5-
// FIXME: should not warn here.
65
double index1(m<double,3,1> X, int i) { return X[i][0]; }
7-
// expected-warning@-1 {{implicit conversion changes signedness: 'int' to 'unsigned long'}}
86

97
double index2(m<double,3,1> X, unsigned i) { return X[i][0]; }
108

119
double index3(m<double,3,1> X, char i) { return X[i][0]; }
12-
// expected-warning@-1 {{implicit conversion changes signedness: 'char' to 'unsigned long'}}
1310

1411
double index4(m<double,3,1> X, int i) { return X[0][i]; }
15-
// expected-warning@-1 {{implicit conversion changes signedness: 'int' to 'unsigned long'}}
1612

1713
double index5(m<double,3,1> X, unsigned i) { return X[0][i]; }
1814

1915
double index6(m<double,3,1> X, char i) { return X[0][i]; }
20-
// expected-warning@-1 {{implicit conversion changes signedness: 'char' to 'unsigned long'}}
16+
17+
// expected-no-diagnostics

0 commit comments

Comments
 (0)