[HLSL][Matrix] Add support for single subscript accessor (#170779)
fixes #166206 - Add swizzle support if row index is constant - Add test cases - Add new AST type - Add new LValue for Matrix Row Type - TODO: Make the new LValue a dynamic index version of ExtVectorElt
This commit is contained in:
parent
26c9598c10
commit
60b6c53f25
@ -106,7 +106,8 @@ Otherwise, the result is a glvalue with type ``cv T`` and with the same value
|
||||
category as ``E1`` which refers to the element at the given row and column in
|
||||
the matrix.
|
||||
|
||||
Programs containing a single subscript expression into a matrix are ill-formed.
|
||||
A single subscript expression into a matrix is legal in HLSL and denotes a
|
||||
vector for the specified row lane, but is ill-formed in C and C++.
|
||||
|
||||
**Note**: We considered providing an expression of the form
|
||||
``postfix-expression [expression]`` to access columns of a matrix. We think
|
||||
|
||||
@ -28,6 +28,7 @@ class ParenExpr;
|
||||
class UnaryOperator;
|
||||
class UnaryExprOrTypeTraitExpr;
|
||||
class ArraySubscriptExpr;
|
||||
class MatrixSingleSubscriptExpr;
|
||||
class MatrixSubscriptExpr;
|
||||
class CompoundLiteralExpr;
|
||||
class ImplicitCastExpr;
|
||||
@ -117,6 +118,7 @@ ExprDependence computeDependence(ParenExpr *E);
|
||||
ExprDependence computeDependence(UnaryOperator *E, const ASTContext &Ctx);
|
||||
ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E);
|
||||
ExprDependence computeDependence(ArraySubscriptExpr *E);
|
||||
ExprDependence computeDependence(MatrixSingleSubscriptExpr *E);
|
||||
ExprDependence computeDependence(MatrixSubscriptExpr *E);
|
||||
ExprDependence computeDependence(CompoundLiteralExpr *E);
|
||||
ExprDependence computeDependence(ImplicitCastExpr *E);
|
||||
|
||||
@ -2790,6 +2790,72 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// MatrixSingleSubscriptExpr - Matrix single subscript expression for the
|
||||
/// MatrixType extension when you want to get\set a vector from a Matrix.
|
||||
class MatrixSingleSubscriptExpr : public Expr {
|
||||
enum { BASE, ROW_IDX, END_EXPR };
|
||||
Stmt *SubExprs[END_EXPR];
|
||||
|
||||
public:
|
||||
/// matrix[row]
|
||||
///
|
||||
/// \param Base The matrix expression.
|
||||
/// \param RowIdx The row index expression.
|
||||
/// \param T The type of the row (usually a vector type).
|
||||
/// \param RBracketLoc Location of the closing ']'.
|
||||
MatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx, QualType T,
|
||||
SourceLocation RBracketLoc)
|
||||
: Expr(MatrixSingleSubscriptExprClass, T,
|
||||
Base->getValueKind(), // lvalue/rvalue follows the matrix base
|
||||
OK_MatrixComponent) {
|
||||
SubExprs[BASE] = Base;
|
||||
SubExprs[ROW_IDX] = RowIdx;
|
||||
ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc;
|
||||
setDependence(computeDependence(this));
|
||||
}
|
||||
|
||||
/// Create an empty matrix single-subscript expression.
|
||||
explicit MatrixSingleSubscriptExpr(EmptyShell Shell)
|
||||
: Expr(MatrixSingleSubscriptExprClass, Shell) {}
|
||||
|
||||
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
|
||||
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
|
||||
void setBase(Expr *E) { SubExprs[BASE] = E; }
|
||||
|
||||
Expr *getRowIdx() { return cast<Expr>(SubExprs[ROW_IDX]); }
|
||||
const Expr *getRowIdx() const { return cast<Expr>(SubExprs[ROW_IDX]); }
|
||||
void setRowIdx(Expr *E) { SubExprs[ROW_IDX] = E; }
|
||||
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return getBase()->getBeginLoc();
|
||||
}
|
||||
|
||||
SourceLocation getEndLoc() const { return getRBracketLoc(); }
|
||||
|
||||
SourceLocation getExprLoc() const LLVM_READONLY {
|
||||
return getBase()->getExprLoc();
|
||||
}
|
||||
|
||||
SourceLocation getRBracketLoc() const {
|
||||
return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
|
||||
}
|
||||
void setRBracketLoc(SourceLocation L) {
|
||||
ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == MatrixSingleSubscriptExprClass;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
|
||||
}
|
||||
};
|
||||
|
||||
/// MatrixSubscriptExpr - Matrix subscript expression for the MatrixType
|
||||
/// extension.
|
||||
/// MatrixSubscriptExpr can be either incomplete (only Base and RowIdx are set
|
||||
|
||||
@ -2894,6 +2894,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
|
||||
// over the children.
|
||||
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
|
||||
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
|
||||
DEF_TRAVERSE_STMT(MatrixSingleSubscriptExpr, {})
|
||||
DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
|
||||
DEF_TRAVERSE_STMT(ArraySectionExpr, {})
|
||||
DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
|
||||
|
||||
@ -540,6 +540,7 @@ protected:
|
||||
class ArrayOrMatrixSubscriptExprBitfields {
|
||||
friend class ArraySubscriptExpr;
|
||||
friend class MatrixSubscriptExpr;
|
||||
friend class MatrixSingleSubscriptExpr;
|
||||
|
||||
LLVM_PREFERRED_TYPE(ExprBitfields)
|
||||
unsigned : NumExprBits;
|
||||
|
||||
@ -153,7 +153,7 @@ namespace clang {
|
||||
/// A bitfield object is a bitfield on a C or C++ record.
|
||||
OK_BitField,
|
||||
|
||||
/// A vector component is an element or range of elements on a vector.
|
||||
/// A vector component is an element or range of elements of a vector.
|
||||
OK_VectorComponent,
|
||||
|
||||
/// An Objective-C property is a logical field of an Objective-C
|
||||
@ -165,7 +165,7 @@ namespace clang {
|
||||
/// Objective-C method calls.
|
||||
OK_ObjCSubscript,
|
||||
|
||||
/// A matrix component is a single element of a matrix.
|
||||
/// A matrix component is a single element or range of elements of a matrix.
|
||||
OK_MatrixComponent
|
||||
};
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ def UnaryOperator : StmtNode<Expr>;
|
||||
def OffsetOfExpr : StmtNode<Expr>;
|
||||
def UnaryExprOrTypeTraitExpr : StmtNode<Expr>;
|
||||
def ArraySubscriptExpr : StmtNode<Expr>;
|
||||
def MatrixSingleSubscriptExpr : StmtNode<Expr>;
|
||||
def MatrixSubscriptExpr : StmtNode<Expr>;
|
||||
def ArraySectionExpr : StmtNode<Expr>;
|
||||
def OMPIteratorExpr : StmtNode<Expr>;
|
||||
|
||||
@ -7405,6 +7405,9 @@ public:
|
||||
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
|
||||
Expr *Idx, SourceLocation RLoc);
|
||||
|
||||
ExprResult CreateBuiltinMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
|
||||
SourceLocation RBLoc);
|
||||
|
||||
ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
|
||||
Expr *ColumnIdx,
|
||||
SourceLocation RBLoc);
|
||||
|
||||
@ -115,6 +115,10 @@ ExprDependence clang::computeDependence(ArraySubscriptExpr *E) {
|
||||
return E->getLHS()->getDependence() | E->getRHS()->getDependence();
|
||||
}
|
||||
|
||||
ExprDependence clang::computeDependence(MatrixSingleSubscriptExpr *E) {
|
||||
return E->getBase()->getDependence() | E->getRowIdx()->getDependence();
|
||||
}
|
||||
|
||||
ExprDependence clang::computeDependence(MatrixSubscriptExpr *E) {
|
||||
return E->getBase()->getDependence() | E->getRowIdx()->getDependence() |
|
||||
(E->getColumnIdx() ? E->getColumnIdx()->getDependence()
|
||||
|
||||
@ -3792,6 +3792,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
|
||||
|
||||
case ParenExprClass:
|
||||
case ArraySubscriptExprClass:
|
||||
case MatrixSingleSubscriptExprClass:
|
||||
case MatrixSubscriptExprClass:
|
||||
case ArraySectionExprClass:
|
||||
case OMPArrayShapingExprClass:
|
||||
|
||||
@ -259,6 +259,9 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
|
||||
}
|
||||
return Cl::CL_LValue;
|
||||
|
||||
case Expr::MatrixSingleSubscriptExprClass:
|
||||
return ClassifyInternal(Ctx, cast<MatrixSingleSubscriptExpr>(E)->getBase());
|
||||
|
||||
// Subscripting matrix types behaves like member accesses.
|
||||
case Expr::MatrixSubscriptExprClass:
|
||||
return ClassifyInternal(Ctx, cast<MatrixSubscriptExpr>(E)->getBase());
|
||||
|
||||
@ -20887,6 +20887,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
|
||||
case Expr::ImaginaryLiteralClass:
|
||||
case Expr::StringLiteralClass:
|
||||
case Expr::ArraySubscriptExprClass:
|
||||
case Expr::MatrixSingleSubscriptExprClass:
|
||||
case Expr::MatrixSubscriptExprClass:
|
||||
case Expr::ArraySectionExprClass:
|
||||
case Expr::OMPArrayShapingExprClass:
|
||||
|
||||
@ -5485,6 +5485,15 @@ recurse:
|
||||
break;
|
||||
}
|
||||
|
||||
case Expr::MatrixSingleSubscriptExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const MatrixSingleSubscriptExpr *ME = cast<MatrixSingleSubscriptExpr>(E);
|
||||
Out << "ix";
|
||||
mangleExpression(ME->getBase());
|
||||
mangleExpression(ME->getRowIdx());
|
||||
break;
|
||||
}
|
||||
|
||||
case Expr::MatrixSubscriptExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const MatrixSubscriptExpr *ME = cast<MatrixSubscriptExpr>(E);
|
||||
|
||||
@ -1690,6 +1690,14 @@ void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
|
||||
OS << "]";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitMatrixSingleSubscriptExpr(
|
||||
MatrixSingleSubscriptExpr *Node) {
|
||||
PrintExpr(Node->getBase());
|
||||
OS << "[";
|
||||
PrintExpr(Node->getRowIdx());
|
||||
OS << "]";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
|
||||
PrintExpr(Node->getBase());
|
||||
OS << "[";
|
||||
|
||||
@ -1510,6 +1510,11 @@ void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitMatrixSingleSubscriptExpr(
|
||||
const MatrixSingleSubscriptExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
@ -1818,6 +1819,8 @@ LValue CodeGenFunction::EmitLValueHelper(const Expr *E,
|
||||
return EmitUnaryOpLValue(cast<UnaryOperator>(E));
|
||||
case Expr::ArraySubscriptExprClass:
|
||||
return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
|
||||
case Expr::MatrixSingleSubscriptExprClass:
|
||||
return EmitMatrixSingleSubscriptExpr(cast<MatrixSingleSubscriptExpr>(E));
|
||||
case Expr::MatrixSubscriptExprClass:
|
||||
return EmitMatrixSubscriptExpr(cast<MatrixSubscriptExpr>(E));
|
||||
case Expr::ArraySectionExprClass:
|
||||
@ -2462,6 +2465,31 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
|
||||
Builder.CreateLoad(LV.getMatrixAddress(), LV.isVolatileQualified());
|
||||
return RValue::get(Builder.CreateExtractElement(Load, Idx, "matrixext"));
|
||||
}
|
||||
if (LV.isMatrixRow()) {
|
||||
QualType MatTy = LV.getType();
|
||||
const ConstantMatrixType *MT = MatTy->castAs<ConstantMatrixType>();
|
||||
|
||||
unsigned NumRows = MT->getNumRows();
|
||||
unsigned NumCols = MT->getNumColumns();
|
||||
|
||||
llvm::Value *MatrixVec = EmitLoadOfScalar(LV, Loc);
|
||||
llvm::Value *Row = LV.getMatrixRowIdx();
|
||||
llvm::Type *ElemTy = ConvertType(MT->getElementType());
|
||||
llvm::Type *RowTy = llvm::FixedVectorType::get(ElemTy, MT->getNumColumns());
|
||||
llvm::Value *Result = llvm::PoisonValue::get(RowTy); // <NumCols x T>
|
||||
|
||||
llvm::MatrixBuilder MB(Builder);
|
||||
|
||||
for (unsigned Col = 0; Col < NumCols; ++Col) {
|
||||
llvm::Value *ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
|
||||
llvm::Value *EltIndex = MB.CreateIndex(Row, ColIdx, NumRows);
|
||||
llvm::Value *Elt = Builder.CreateExtractElement(MatrixVec, EltIndex);
|
||||
llvm::Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
|
||||
Result = Builder.CreateInsertElement(Result, Elt, Lane);
|
||||
}
|
||||
|
||||
return RValue::get(Result);
|
||||
}
|
||||
|
||||
assert(LV.isBitField() && "Unknown LValue type!");
|
||||
return EmitLoadOfBitfieldLValue(LV, Loc);
|
||||
@ -2689,6 +2717,31 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
|
||||
addInstToCurrentSourceAtom(I, Vec);
|
||||
return;
|
||||
}
|
||||
if (Dst.isMatrixRow()) {
|
||||
QualType MatTy = Dst.getType();
|
||||
const ConstantMatrixType *MT = MatTy->castAs<ConstantMatrixType>();
|
||||
|
||||
unsigned NumRows = MT->getNumRows();
|
||||
unsigned NumCols = MT->getNumColumns();
|
||||
|
||||
llvm::Value *MatrixVec =
|
||||
Builder.CreateLoad(Dst.getAddress(), "matrix.load");
|
||||
|
||||
llvm::Value *Row = Dst.getMatrixRowIdx();
|
||||
llvm::Value *RowVal = Src.getScalarVal(); // <NumCols x T>
|
||||
llvm::MatrixBuilder MB(Builder);
|
||||
|
||||
for (unsigned Col = 0; Col < NumCols; ++Col) {
|
||||
llvm::Value *ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
|
||||
llvm::Value *EltIndex = MB.CreateIndex(Row, ColIdx, NumRows);
|
||||
llvm::Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
|
||||
llvm::Value *NewElt = Builder.CreateExtractElement(RowVal, Lane);
|
||||
MatrixVec = Builder.CreateInsertElement(MatrixVec, NewElt, EltIndex);
|
||||
}
|
||||
|
||||
Builder.CreateStore(MatrixVec, Dst.getAddress());
|
||||
return;
|
||||
}
|
||||
|
||||
assert(Dst.isBitField() && "Unknown LValue type");
|
||||
return EmitStoreThroughBitfieldLValue(Src, Dst);
|
||||
@ -4904,6 +4957,34 @@ llvm::Value *CodeGenFunction::EmitMatrixIndexExpr(const Expr *E) {
|
||||
return Builder.CreateIntCast(Idx, IntPtrTy, IsSigned);
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::EmitMatrixSingleSubscriptExpr(
|
||||
const MatrixSingleSubscriptExpr *E) {
|
||||
LValue Base = EmitLValue(E->getBase());
|
||||
llvm::Value *RowIdx = EmitMatrixIndexExpr(E->getRowIdx());
|
||||
|
||||
if (auto *RowConst = llvm::dyn_cast<llvm::ConstantInt>(RowIdx)) {
|
||||
// Extract matrix shape from the AST type
|
||||
const auto *MatTy = E->getBase()->getType()->castAs<ConstantMatrixType>();
|
||||
unsigned NumCols = MatTy->getNumColumns();
|
||||
llvm::SmallVector<llvm::Constant *, 8> Indices;
|
||||
Indices.reserve(NumCols);
|
||||
|
||||
unsigned Row = RowConst->getZExtValue();
|
||||
unsigned Start = Row * NumCols;
|
||||
for (unsigned C = 0; C < NumCols; ++C)
|
||||
Indices.push_back(llvm::ConstantInt::get(Int32Ty, Start + C));
|
||||
|
||||
llvm::Constant *Elts = llvm::ConstantVector::get(Indices);
|
||||
return LValue::MakeExtVectorElt(
|
||||
MaybeConvertMatrixAddress(Base.getAddress(), *this), Elts,
|
||||
E->getBase()->getType(), Base.getBaseInfo(), TBAAAccessInfo());
|
||||
}
|
||||
|
||||
return LValue::MakeMatrixRow(
|
||||
MaybeConvertMatrixAddress(Base.getAddress(), *this), RowIdx,
|
||||
E->getBase()->getType(), Base.getBaseInfo(), TBAAAccessInfo());
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E) {
|
||||
assert(
|
||||
!E->isIncomplete() &&
|
||||
@ -5176,6 +5257,9 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
|
||||
return LValue::MakeExtVectorElt(Base.getAddress(), CV, type,
|
||||
Base.getBaseInfo(), TBAAAccessInfo());
|
||||
}
|
||||
if (Base.isMatrixRow())
|
||||
return EmitUnsupportedLValue(E, "Matrix single index swizzle");
|
||||
|
||||
assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
|
||||
|
||||
llvm::Constant *BaseElts = Base.getExtVectorElts();
|
||||
|
||||
@ -602,6 +602,7 @@ public:
|
||||
}
|
||||
|
||||
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
|
||||
Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
|
||||
Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
|
||||
Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
|
||||
Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
|
||||
@ -2112,6 +2113,39 @@ Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
||||
return Builder.CreateExtractElement(Base, Idx, "vecext");
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
|
||||
MatrixSingleSubscriptExpr *E) {
|
||||
TestAndClearIgnoreResultAssign();
|
||||
|
||||
auto *MatrixTy = E->getBase()->getType()->castAs<ConstantMatrixType>();
|
||||
unsigned NumRows = MatrixTy->getNumRows();
|
||||
unsigned NumColumns = MatrixTy->getNumColumns();
|
||||
|
||||
// Row index
|
||||
Value *RowIdx = CGF.EmitMatrixIndexExpr(E->getRowIdx());
|
||||
llvm::MatrixBuilder MB(Builder);
|
||||
|
||||
// The row index must be in [0, NumRows)
|
||||
if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0)
|
||||
MB.CreateIndexAssumption(RowIdx, NumRows);
|
||||
|
||||
Value *FlatMatrix = Visit(E->getBase());
|
||||
llvm::Type *ElemTy = CGF.ConvertType(MatrixTy->getElementType());
|
||||
auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
|
||||
Value *RowVec = llvm::PoisonValue::get(ResultTy);
|
||||
|
||||
for (unsigned Col = 0; Col != NumColumns; ++Col) {
|
||||
Value *ColVal = llvm::ConstantInt::get(RowIdx->getType(), Col);
|
||||
Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, "matrix_row_idx");
|
||||
Value *Elt =
|
||||
Builder.CreateExtractElement(FlatMatrix, EltIdx, "matrix_elem");
|
||||
Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
|
||||
RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane, "matrix_row_ins");
|
||||
}
|
||||
|
||||
return RowVec;
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
|
||||
TestAndClearIgnoreResultAssign();
|
||||
|
||||
|
||||
@ -187,7 +187,8 @@ class LValue {
|
||||
BitField, // This is a bitfield l-value, use getBitfield*.
|
||||
ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
|
||||
GlobalReg, // This is a register l-value, use getGlobalReg()
|
||||
MatrixElt // This is a matrix element, use getVector*
|
||||
MatrixElt, // This is a matrix element, use getVector*
|
||||
MatrixRow // This is a matrix vector subset, use getVector*
|
||||
} LVType;
|
||||
|
||||
union {
|
||||
@ -199,6 +200,9 @@ class LValue {
|
||||
// Index into a vector subscript: V[i]
|
||||
llvm::Value *VectorIdx;
|
||||
|
||||
// Index into a matrix row subscript: M[i]
|
||||
llvm::Value *MatrixRowIdx;
|
||||
|
||||
// ExtVector element subset: V.xyx
|
||||
llvm::Constant *VectorElts;
|
||||
|
||||
@ -282,6 +286,7 @@ public:
|
||||
bool isExtVectorElt() const { return LVType == ExtVectorElt; }
|
||||
bool isGlobalReg() const { return LVType == GlobalReg; }
|
||||
bool isMatrixElt() const { return LVType == MatrixElt; }
|
||||
bool isMatrixRow() const { return LVType == MatrixRow; }
|
||||
|
||||
bool isVolatileQualified() const { return Quals.hasVolatile(); }
|
||||
bool isRestrictQualified() const { return Quals.hasRestrict(); }
|
||||
@ -398,6 +403,11 @@ public:
|
||||
return VectorIdx;
|
||||
}
|
||||
|
||||
llvm::Value *getMatrixRowIdx() const {
|
||||
assert(isMatrixRow());
|
||||
return MatrixRowIdx;
|
||||
}
|
||||
|
||||
// extended vector elements.
|
||||
Address getExtVectorAddress() const {
|
||||
assert(isExtVectorElt());
|
||||
@ -486,6 +496,16 @@ public:
|
||||
return R;
|
||||
}
|
||||
|
||||
static LValue MakeMatrixRow(Address Addr, llvm::Value *RowIdx,
|
||||
QualType MatrixTy, LValueBaseInfo BaseInfo,
|
||||
TBAAAccessInfo TBAAInfo) {
|
||||
LValue LV;
|
||||
LV.LVType = MatrixRow;
|
||||
LV.MatrixRowIdx = RowIdx; // store the row index here
|
||||
LV.Initialize(MatrixTy, MatrixTy.getQualifiers(), Addr, BaseInfo, TBAAInfo);
|
||||
return LV;
|
||||
}
|
||||
|
||||
static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx,
|
||||
QualType type, LValueBaseInfo BaseInfo,
|
||||
TBAAAccessInfo TBAAInfo) {
|
||||
|
||||
@ -4414,6 +4414,7 @@ public:
|
||||
LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
|
||||
bool Accessed = false);
|
||||
llvm::Value *EmitMatrixIndexExpr(const Expr *E);
|
||||
LValue EmitMatrixSingleSubscriptExpr(const MatrixSingleSubscriptExpr *E);
|
||||
LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E);
|
||||
LValue EmitArraySectionExpr(const ArraySectionExpr *E,
|
||||
bool IsLowerBound = true);
|
||||
|
||||
@ -1303,6 +1303,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
|
||||
// Some might be dependent for other reasons.
|
||||
case Expr::ArraySubscriptExprClass:
|
||||
case Expr::MatrixSubscriptExprClass:
|
||||
case Expr::MatrixSingleSubscriptExprClass:
|
||||
case Expr::ArraySectionExprClass:
|
||||
case Expr::OMPArrayShapingExprClass:
|
||||
case Expr::OMPIteratorExprClass:
|
||||
|
||||
@ -5090,6 +5090,62 @@ ExprResult Sema::tryConvertExprToType(Expr *E, QualType Ty) {
|
||||
return InitSeq.Perform(*this, Entity, Kind, E);
|
||||
}
|
||||
|
||||
ExprResult Sema::CreateBuiltinMatrixSingleSubscriptExpr(Expr *Base,
|
||||
Expr *RowIdx,
|
||||
SourceLocation RBLoc) {
|
||||
ExprResult BaseR = CheckPlaceholderExpr(Base);
|
||||
if (BaseR.isInvalid())
|
||||
return BaseR;
|
||||
Base = BaseR.get();
|
||||
|
||||
ExprResult RowR = CheckPlaceholderExpr(RowIdx);
|
||||
if (RowR.isInvalid())
|
||||
return RowR;
|
||||
RowIdx = RowR.get();
|
||||
|
||||
// Build an unanalyzed expression if any of the operands is type-dependent.
|
||||
if (Base->isTypeDependent() || RowIdx->isTypeDependent())
|
||||
return new (Context)
|
||||
MatrixSingleSubscriptExpr(Base, RowIdx, Context.DependentTy, RBLoc);
|
||||
|
||||
// Check that IndexExpr is an integer expression. If it is a constant
|
||||
// expression, check that it is less than Dim (= the number of elements in the
|
||||
// corresponding dimension).
|
||||
auto IsIndexValid = [&](Expr *IndexExpr, unsigned Dim,
|
||||
bool IsColumnIdx) -> Expr * {
|
||||
if (!IndexExpr->getType()->isIntegerType() &&
|
||||
!IndexExpr->isTypeDependent()) {
|
||||
Diag(IndexExpr->getBeginLoc(), diag::err_matrix_index_not_integer)
|
||||
<< IsColumnIdx;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (std::optional<llvm::APSInt> Idx =
|
||||
IndexExpr->getIntegerConstantExpr(Context)) {
|
||||
if ((*Idx < 0 || *Idx >= Dim)) {
|
||||
Diag(IndexExpr->getBeginLoc(), diag::err_matrix_index_outside_range)
|
||||
<< IsColumnIdx << Dim;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ExprResult ConvExpr = IndexExpr;
|
||||
assert(!ConvExpr.isInvalid() &&
|
||||
"should be able to convert any integer type to size type");
|
||||
return ConvExpr.get();
|
||||
};
|
||||
|
||||
auto *MTy = Base->getType()->getAs<ConstantMatrixType>();
|
||||
RowIdx = IsIndexValid(RowIdx, MTy->getNumRows(), false);
|
||||
if (!RowIdx)
|
||||
return ExprError();
|
||||
|
||||
QualType RowVecQT =
|
||||
Context.getExtVectorType(MTy->getElementType(), MTy->getNumColumns());
|
||||
|
||||
return new (Context) MatrixSingleSubscriptExpr(Base, RowIdx, RowVecQT, RBLoc);
|
||||
}
|
||||
|
||||
ExprResult Sema::CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
|
||||
Expr *ColumnIdx,
|
||||
SourceLocation RBLoc) {
|
||||
@ -21582,12 +21638,17 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
case BuiltinType::IncompleteMatrixIdx:
|
||||
Diag(cast<MatrixSubscriptExpr>(E->IgnoreParens())
|
||||
->getRowIdx()
|
||||
->getBeginLoc(),
|
||||
diag::err_matrix_incomplete_index);
|
||||
case BuiltinType::IncompleteMatrixIdx: {
|
||||
auto *MS = cast<MatrixSubscriptExpr>(E->IgnoreParens());
|
||||
// At this point, we know there was no second [] to complete the operator.
|
||||
// In HLSL, treat "m[row]" as selecting a row lane of column sized vector.
|
||||
if (getLangOpts().HLSL) {
|
||||
return CreateBuiltinMatrixSingleSubscriptExpr(
|
||||
MS->getBase(), MS->getRowIdx(), E->getExprLoc());
|
||||
}
|
||||
Diag(MS->getRowIdx()->getBeginLoc(), diag::err_matrix_incomplete_index);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
// Expressions of unknown type.
|
||||
case BuiltinType::ArraySection:
|
||||
|
||||
@ -2849,6 +2849,16 @@ public:
|
||||
RBracketLoc);
|
||||
}
|
||||
|
||||
/// Build a new matrix single subscript expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
|
||||
SourceLocation RBracketLoc) {
|
||||
return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
|
||||
RBracketLoc);
|
||||
}
|
||||
|
||||
/// Build a new matrix subscript expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
@ -13395,6 +13405,25 @@ TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
|
||||
/*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
|
||||
MatrixSingleSubscriptExpr *E) {
|
||||
ExprResult Base = getDerived().TransformExpr(E->getBase());
|
||||
if (Base.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
|
||||
if (RowIdx.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
|
||||
RowIdx.get() == E->getRowIdx())
|
||||
return E;
|
||||
|
||||
return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
|
||||
E->getRBracketLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
|
||||
|
||||
@ -968,6 +968,14 @@ void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
||||
E->setRBracketLoc(readSourceLocation());
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitMatrixSingleSubscriptExpr(
|
||||
MatrixSingleSubscriptExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->setBase(Record.readSubExpr());
|
||||
E->setRowIdx(Record.readSubExpr());
|
||||
E->setRBracketLoc(readSourceLocation());
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->setBase(Record.readSubExpr());
|
||||
|
||||
@ -907,6 +907,15 @@ void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
||||
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitMatrixSingleSubscriptExpr(
|
||||
MatrixSingleSubscriptExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.AddStmt(E->getBase());
|
||||
Record.AddStmt(E->getRowIdx());
|
||||
Record.AddSourceLocation(E->getRBracketLoc());
|
||||
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.AddStmt(E->getBase());
|
||||
|
||||
@ -2083,6 +2083,11 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||
Bldr.addNodes(Dst);
|
||||
break;
|
||||
|
||||
case Stmt::MatrixSingleSubscriptExprClass:
|
||||
llvm_unreachable(
|
||||
"Support for MatrixSingleSubscriptExprClass is not implemented.");
|
||||
break;
|
||||
|
||||
case Stmt::MatrixSubscriptExprClass:
|
||||
llvm_unreachable("Support for MatrixSubscriptExpr is not implemented.");
|
||||
break;
|
||||
|
||||
122
clang/test/AST/HLSL/matrix-single-subscript-getter.hlsl
Normal file
122
clang/test/AST/HLSL/matrix-single-subscript-getter.hlsl
Normal file
@ -0,0 +1,122 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -o - %s | FileCheck %s
|
||||
|
||||
typedef float float4x4 __attribute__((matrix_type(4,4)));
|
||||
typedef int int4x4 __attribute__((matrix_type(4,4)));
|
||||
|
||||
typedef float float4 __attribute__((ext_vector_type(4)));
|
||||
typedef int int4 __attribute__((ext_vector_type(4)));
|
||||
|
||||
export float4 getFloatMatrixDynamic(float4x4 M, int index) {
|
||||
// CHECK: FunctionDecl {{.*}} used getFloatMatrixDynamic 'float4 (float4x4, int)'
|
||||
// CHECK: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4':'matrix<float, 4, 4>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'index' 'int'
|
||||
return M[index];
|
||||
}
|
||||
|
||||
export int4 getIntMatrixDynamic(int4x4 M, int index) {
|
||||
// CHECK: FunctionDecl {{.*}} used getIntMatrixDynamic 'int4 (int4x4, int)'
|
||||
// CHECK: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'index' 'int'
|
||||
return M[index];
|
||||
}
|
||||
|
||||
export float4 AddFloatMatrixConstant(float4x4 M) {
|
||||
// CHECK: FunctionDecl {{.*}} used AddFloatMatrixConstant 'float4 (float4x4)'
|
||||
// CHECK: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'vector<float, 4>' '+'
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'vector<float, 4>' '+'
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'vector<float, 4>' '+'
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4':'matrix<float, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4':'matrix<float, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4':'matrix<float, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4':'matrix<float, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
|
||||
return M[0] + M[1] + M[2] + M[3];
|
||||
}
|
||||
|
||||
export int4 AddIntMatrixConstant(int4x4 M) {
|
||||
// CHECK: FunctionDecl {{.*}} used AddIntMatrixConstant 'int4 (int4x4)'
|
||||
// CHECK: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'vector<int, 4>' '+'
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'vector<int, 4>' '+'
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'vector<int, 4>' '+'
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
|
||||
return M[0] + M[1] + M[2] + M[3];
|
||||
}
|
||||
|
||||
export vector<bool, 3> getBoolVecFromTemplateMat(matrix<bool, 2, 3> M) {
|
||||
// CHECK: FunctionDecl {{.*}} used getBoolVecFromTemplateMat 'vector<bool, 3> (matrix<bool, 2, 3>)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} used M 'matrix<bool, 2, 3>'
|
||||
// CHECK-NEXT: CompoundStmt {{.*}}
|
||||
// CHECK-NEXT: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<bool, 3>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<bool, 3>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'matrix<bool, 2, 3>' lvalue ParmVar {{.*}} 'M' 'matrix<bool, 2, 3>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}}'int' 0
|
||||
return M[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
vector<T, 3> getVecFromTemplateMat(matrix<T, 2, 3> M) {
|
||||
// CHECK: FunctionTemplateDecl {{.*}} getVecFromTemplateMat
|
||||
// CHECK-NEXT: TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
|
||||
// CHECK-NEXT: FunctionDecl {{.*}} getVecFromTemplateMat 'vector<T, 3> (matrix<T, 2, 3>)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} referenced M 'matrix<T, 2, 3>'
|
||||
// CHECK-NEXT: CompoundStmt {{.*}}
|
||||
// CHECK-NEXT: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: MatrixSubscriptExpr {{.*}} '<incomplete matrix index type>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'matrix<T, 2, 3>' lvalue ParmVar {{.*}} 'M' 'matrix<T, 2, 3>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0
|
||||
// CHECK-NEXT: <<<NULL>>>
|
||||
// CHECK-NEXT: FunctionDecl {{.*}} used getVecFromTemplateMat 'vector<bool, 3> (matrix<bool, 2, 3>)' implicit_instantiation instantiated_from {{.*}}
|
||||
// CHECK-NEXT: TemplateArgument type 'bool'
|
||||
// CHECK-NEXT: BuiltinType {{.*}} 'bool'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} used M 'matrix<bool, 2, 3>'
|
||||
// CHECK-NEXT: CompoundStmt {{.*}}
|
||||
// CHECK-NEXT: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<bool, 3>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<bool, 3>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:12> 'matrix<bool, 2, 3>' lvalue ParmVar {{.*}} 'M' 'matrix<bool, 2, 3>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} <col:14> 'int' 0
|
||||
// CHECK-NEXT: TypedefDecl {{.*}} referenced bool3 'vector<bool, 3>'
|
||||
return M[0];
|
||||
}
|
||||
|
||||
typedef bool bool3 __attribute__((ext_vector_type(3)));
|
||||
typedef bool bool2x3 __attribute__((matrix_type(2,3)));
|
||||
|
||||
export bool3 testTemplatedMatrixAccess(bool2x3 M) {
|
||||
return getVecFromTemplateMat(M);
|
||||
}
|
||||
59
clang/test/AST/HLSL/matrix-single-subscript-setter.hlsl
Normal file
59
clang/test/AST/HLSL/matrix-single-subscript-setter.hlsl
Normal file
@ -0,0 +1,59 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -o - %s | FileCheck %s
|
||||
|
||||
typedef float float4x4 __attribute__((matrix_type(4,4)));
|
||||
typedef int int4x4 __attribute__((matrix_type(4,4)));
|
||||
|
||||
typedef float float4 __attribute__((ext_vector_type(4)));
|
||||
typedef int int4 __attribute__((ext_vector_type(4)));
|
||||
|
||||
export void setMatrix(out float4x4 M, int index, float4 V) {
|
||||
// CHECK: BinaryOperator{{.*}} 'vector<float, 4>' lvalue matrixcomponent '='
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4 &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'index' 'int'
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4':'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4':'vector<float, 4>' lvalue ParmVar {{.*}} 'V' 'float4':'vector<float, 4>'
|
||||
M[index] = V;
|
||||
}
|
||||
|
||||
export void setMatrixConstIndex(out int4x4 M, int4x4 N ) {
|
||||
// CHECK: BinaryOperator {{.*}} 'vector<int, 4>' lvalue matrixcomponent '='
|
||||
// CHECK: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4 &__restrict'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'N' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
|
||||
M[0] = N[3];
|
||||
|
||||
// CHECK: BinaryOperator {{.*}} 'vector<int, 4>' lvalue matrixcomponent '='
|
||||
// CHECK: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4 &__restrict'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'N' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
|
||||
M[1] = N[2];
|
||||
|
||||
// CHECK: BinaryOperator {{.*}} 'vector<int, 4>' lvalue matrixcomponent '='
|
||||
// CHECK: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4 &__restrict'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'N' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
|
||||
M[2] = N[1];
|
||||
|
||||
// CHECK: BinaryOperator {{.*}} 'vector<int, 4>' lvalue matrixcomponent '='
|
||||
// CHECK: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4 &__restrict'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'N' 'int4x4':'matrix<int, 4, 4>'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0
|
||||
M[3] = N[0];
|
||||
}
|
||||
56
clang/test/AST/HLSL/matrix-single-subscript-swizzle.hlsl
Normal file
56
clang/test/AST/HLSL/matrix-single-subscript-swizzle.hlsl
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -o - %s | FileCheck %s
|
||||
|
||||
typedef float float4x4 __attribute__((matrix_type(4,4)));
|
||||
typedef int int4x4 __attribute__((matrix_type(4,4)));
|
||||
|
||||
typedef float float4 __attribute__((ext_vector_type(4)));
|
||||
typedef float float3 __attribute__((ext_vector_type(3)));
|
||||
typedef int int4 __attribute__((ext_vector_type(4)));
|
||||
|
||||
export void setMatrix(out float4x4 M, int index, float4 V) {
|
||||
// CHECK: FunctionDecl {{.*}} used setMatrix 'void (out float4x4, int, float4)'
|
||||
// CHECK: BinaryOperator {{.*}} 'float4':'vector<float, 4>' lvalue vectorcomponent '='
|
||||
// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'float4':'vector<float, 4>' lvalue vectorcomponent abgr
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4 &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'index' 'int'
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4':'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4':'vector<float, 4>' lvalue ParmVar {{.*}} 'V' 'float4':'vector<float, 4>'
|
||||
M[index].abgr = V;
|
||||
}
|
||||
|
||||
export void setMatrix1(out float4x4 M, float4 V) {
|
||||
// CHECK: FunctionDecl {{.*}} used setMatrix1 'void (out float4x4, float4)'
|
||||
// CHECK: BinaryOperator {{.*}} 'float4':'vector<float, 4>' lvalue vectorcomponent '='
|
||||
// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'float4':'vector<float, 4>' lvalue vectorcomponent abgr
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4 &__restrict'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4':'vector<float, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4':'vector<float, 4>' lvalue ParmVar {{.*}} 'V' 'float4':'vector<float, 4>'
|
||||
M[3].abgr = V;
|
||||
}
|
||||
|
||||
export void setMatrix2(out int4x4 M, int4 V) {
|
||||
// CHECK: FunctionDecl {{.*}} used setMatrix2 'void (out int4x4, int4)'
|
||||
// CHECK: BinaryOperator {{.*}} 'int4':'vector<int, 4>' lvalue vectorcomponent '='
|
||||
// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'int4':'vector<int, 4>' lvalue vectorcomponent rgba
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<int, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4x4':'matrix<int, 4, 4>' lvalue ParmVar {{.*}} 'M' 'int4x4 &__restrict'
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int4':'vector<int, 4>' <LValueToRValue>
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int4':'vector<int, 4>' lvalue ParmVar {{.*}} 'V' 'int4':'vector<int, 4>'
|
||||
M[2].rgba = V;
|
||||
}
|
||||
|
||||
export float3 getMatrix(float4x4 M, int index) {
|
||||
// CHECK: FunctionDecl {{.*}} used getMatrix 'float3 (float4x4, int)'
|
||||
// CHECK: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float3':'vector<float, 3>' <LValueToRValue>
|
||||
// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'float3':'vector<float, 3>' lvalue vectorcomponent rgb
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 4>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float4x4':'matrix<float, 4, 4>' lvalue ParmVar {{.*}} 'M' 'float4x4':'matrix<float, 4, 4>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'index' 'int'
|
||||
return M[index].rgb;
|
||||
}
|
||||
16
clang/test/AST/HLSL/pch_with_matrix_single_subscript.hlsl
Normal file
16
clang/test/AST/HLSL/pch_with_matrix_single_subscript.hlsl
Normal file
@ -0,0 +1,16 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -finclude-default-header -emit-pch -o %t %S/Inputs/pch.hlsl
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -finclude-default-header -include-pch %t -ast-dump-all %s | FileCheck %s
|
||||
|
||||
float3x2 gM;
|
||||
|
||||
// CHECK: FunctionDecl {{.*}} getRow 'float2 (uint)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} col:20 used row 'uint':'unsigned int'
|
||||
// CHECK-NEXT: CompoundStmt {{.*}}
|
||||
// CHECK-NEXT: ReturnStmt {{.*}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector<float, 2>' <LValueToRValue>
|
||||
// CHECK-NEXT: MatrixSingleSubscriptExpr {{.*}} 'vector<float, 2>' lvalue matrixcomponent
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl_constant float3x2':'matrix<float hlsl_constant, 3, 2>' lvalue Var {{.*}} 'gM' 'hlsl_constant float3x2':'matrix<float hlsl_constant, 3, 2>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'uint':'unsigned int' lvalue ParmVar {{.*}} 'row' 'uint':'unsigned int'
|
||||
float2 getRow(uint row) {
|
||||
return gM[row];
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: define hidden void @_Z10setMatrix1Ru11matrix_typeILm4ELm4EfEDv4_f(
|
||||
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(64) [[M:%.*]], <4 x float> noundef nofpclass(nan inf) [[V:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
|
||||
// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <4 x float>, align 16
|
||||
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store <4 x float> [[V]], ptr [[V_ADDR]], align 16
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[V_ADDR]], align 16
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3:![0-9]+]], !align [[META4:![0-9]+]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP0]], i32 0
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 15
|
||||
// CHECK-NEXT: store float [[TMP2]], ptr [[TMP3]], align 4
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP0]], i32 1
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 14
|
||||
// CHECK-NEXT: store float [[TMP4]], ptr [[TMP5]], align 4
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x float> [[TMP0]], i32 2
|
||||
// CHECK-NEXT: [[TMP7:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 13
|
||||
// CHECK-NEXT: store float [[TMP6]], ptr [[TMP7]], align 4
|
||||
// CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x float> [[TMP0]], i32 3
|
||||
// CHECK-NEXT: [[TMP9:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 12
|
||||
// CHECK-NEXT: store float [[TMP8]], ptr [[TMP9]], align 4
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void setMatrix1(out float4x4 M, float4 V) {
|
||||
M[3].abgr = V;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden void @_Z10setMatrix2Ru11matrix_typeILm4ELm4EiEDv4_i(
|
||||
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(64) [[M:%.*]], <4 x i32> noundef [[V:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
|
||||
// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <4 x i32>, align 16
|
||||
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store <4 x i32> [[V]], ptr [[V_ADDR]], align 16
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[V_ADDR]], align 16
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[TMP0]], i32 0
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr <16 x i32>, ptr [[TMP1]], i32 0, i32 8
|
||||
// CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP3]], align 4
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> [[TMP0]], i32 1
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = getelementptr <16 x i32>, ptr [[TMP1]], i32 0, i32 9
|
||||
// CHECK-NEXT: store i32 [[TMP4]], ptr [[TMP5]], align 4
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x i32> [[TMP0]], i32 2
|
||||
// CHECK-NEXT: [[TMP7:%.*]] = getelementptr <16 x i32>, ptr [[TMP1]], i32 0, i32 10
|
||||
// CHECK-NEXT: store i32 [[TMP6]], ptr [[TMP7]], align 4
|
||||
// CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i32> [[TMP0]], i32 3
|
||||
// CHECK-NEXT: [[TMP9:%.*]] = getelementptr <16 x i32>, ptr [[TMP1]], i32 0, i32 11
|
||||
// CHECK-NEXT: store i32 [[TMP8]], ptr [[TMP9]], align 4
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void setMatrix2(out int4x4 M, int4 V) {
|
||||
M[2].rgba = V;
|
||||
}
|
||||
//.
|
||||
// CHECK: [[META3]] = !{}
|
||||
// CHECK: [[META4]] = !{i64 4}
|
||||
//.
|
||||
@ -0,0 +1,11 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s
|
||||
// BUG: https://github.com/llvm/llvm-project/issues/170777
|
||||
// XFAIL: *
|
||||
|
||||
void setMatrix(out float4x4 M, int index, float4 V) {
|
||||
M[index].abgr = V;
|
||||
}
|
||||
|
||||
float3 getMatrix(float4x4 M, int index) {
|
||||
return M[index].rgb;
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z24getFloatVecMatrixDynamicu11matrix_typeILm4ELm4EfEi(
|
||||
// CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [16 x float], align 4
|
||||
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: store <16 x float> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP2]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <4 x float> poison, float [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = add i32 4, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM1:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP3]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS]], float [[MATRIX_ELEM1]], i32 1
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = add i32 8, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM3:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP4]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS2]], float [[MATRIX_ELEM3]], i32 2
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = add i32 12, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM5:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP5]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS4]], float [[MATRIX_ELEM5]], i32 3
|
||||
// CHECK-NEXT: ret <4 x float> [[MATRIX_ROW_INS6]]
|
||||
//
|
||||
float4 getFloatVecMatrixDynamic(float4x4 M, int index) {
|
||||
return M[index];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z27getFloatScalarMatrixDynamicu11matrix_typeILm2ELm1EfEi(
|
||||
// CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [2 x float], align 4
|
||||
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: store <2 x float> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <2 x float> [[TMP1]], i32 [[TMP2]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <1 x float> poison, float [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[CAST_VTRUNC:%.*]] = extractelement <1 x float> [[MATRIX_ROW_INS]], i32 0
|
||||
// CHECK-NEXT: ret float [[CAST_VTRUNC]]
|
||||
//
|
||||
float getFloatScalarMatrixDynamic(float2x1 M, int index) {
|
||||
return M[index];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z28getFloatScalarMatrixConstantu11matrix_typeILm2ELm1EfE(
|
||||
// CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [2 x float], align 4
|
||||
// CHECK-NEXT: store <2 x float> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <2 x float> [[TMP0]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <1 x float> poison, float [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[CAST_VTRUNC:%.*]] = extractelement <1 x float> [[MATRIX_ROW_INS]], i32 0
|
||||
// CHECK-NEXT: ret float [[CAST_VTRUNC]]
|
||||
//
|
||||
float getFloatScalarMatrixConstant(float2x1 M) {
|
||||
return M[0];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z29getFloatScalarMatrixConstant2u11matrix_typeILm2ELm1EfE(
|
||||
// CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [2 x float], align 4
|
||||
// CHECK-NEXT: store <2 x float> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <2 x float> [[TMP0]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <1 x float> poison, float [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[CAST_VTRUNC:%.*]] = extractelement <1 x float> [[MATRIX_ROW_INS]], i32 0
|
||||
// CHECK-NEXT: ret float [[CAST_VTRUNC]]
|
||||
//
|
||||
float getFloatScalarMatrixConstant2(float2x1 M) {
|
||||
return M[1];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden noundef <4 x i32> @_Z19getIntMatrixDynamicu11matrix_typeILm4ELm4EiEi(
|
||||
// CHECK-SAME: <16 x i32> noundef [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [16 x i32], align 4
|
||||
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: store <16 x i32> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <16 x i32> [[TMP1]], i32 [[TMP2]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = add i32 4, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM1:%.*]] = extractelement <16 x i32> [[TMP1]], i32 [[TMP3]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS]], i32 [[MATRIX_ELEM1]], i32 1
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = add i32 8, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM3:%.*]] = extractelement <16 x i32> [[TMP1]], i32 [[TMP4]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS2]], i32 [[MATRIX_ELEM3]], i32 2
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = add i32 12, [[TMP0]]
|
||||
// CHECK-NEXT: [[MATRIX_ELEM5:%.*]] = extractelement <16 x i32> [[TMP1]], i32 [[TMP5]]
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS4]], i32 [[MATRIX_ELEM5]], i32 3
|
||||
// CHECK-NEXT: ret <4 x i32> [[MATRIX_ROW_INS6]]
|
||||
//
|
||||
int4 getIntMatrixDynamic(int4x4 M, int index) {
|
||||
return M[index];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z22AddFloatMatrixConstantu11matrix_typeILm4ELm4EfE(
|
||||
// CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [16 x float], align 4
|
||||
// CHECK-NEXT: store <16 x float> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <16 x float> [[TMP0]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <4 x float> poison, float [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM1:%.*]] = extractelement <16 x float> [[TMP0]], i32 4
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS]], float [[MATRIX_ELEM1]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM3:%.*]] = extractelement <16 x float> [[TMP0]], i32 8
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS2]], float [[MATRIX_ELEM3]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM5:%.*]] = extractelement <16 x float> [[TMP0]], i32 12
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS4]], float [[MATRIX_ELEM5]], i32 3
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM7:%.*]] = extractelement <16 x float> [[TMP1]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS8:%.*]] = insertelement <4 x float> poison, float [[MATRIX_ELEM7]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM9:%.*]] = extractelement <16 x float> [[TMP1]], i32 5
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS10:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS8]], float [[MATRIX_ELEM9]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM11:%.*]] = extractelement <16 x float> [[TMP1]], i32 9
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS12:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS10]], float [[MATRIX_ELEM11]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM13:%.*]] = extractelement <16 x float> [[TMP1]], i32 13
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS14:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS12]], float [[MATRIX_ELEM13]], i32 3
|
||||
// CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nnan ninf nsz arcp afn <4 x float> [[MATRIX_ROW_INS6]], [[MATRIX_ROW_INS14]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM15:%.*]] = extractelement <16 x float> [[TMP2]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS16:%.*]] = insertelement <4 x float> poison, float [[MATRIX_ELEM15]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM17:%.*]] = extractelement <16 x float> [[TMP2]], i32 6
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS18:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS16]], float [[MATRIX_ELEM17]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM19:%.*]] = extractelement <16 x float> [[TMP2]], i32 10
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS20:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS18]], float [[MATRIX_ELEM19]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM21:%.*]] = extractelement <16 x float> [[TMP2]], i32 14
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS22:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS20]], float [[MATRIX_ELEM21]], i32 3
|
||||
// CHECK-NEXT: [[ADD23:%.*]] = fadd reassoc nnan ninf nsz arcp afn <4 x float> [[ADD]], [[MATRIX_ROW_INS22]]
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM24:%.*]] = extractelement <16 x float> [[TMP3]], i32 3
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS25:%.*]] = insertelement <4 x float> poison, float [[MATRIX_ELEM24]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM26:%.*]] = extractelement <16 x float> [[TMP3]], i32 7
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS27:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS25]], float [[MATRIX_ELEM26]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM28:%.*]] = extractelement <16 x float> [[TMP3]], i32 11
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS29:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS27]], float [[MATRIX_ELEM28]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM30:%.*]] = extractelement <16 x float> [[TMP3]], i32 15
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS31:%.*]] = insertelement <4 x float> [[MATRIX_ROW_INS29]], float [[MATRIX_ELEM30]], i32 3
|
||||
// CHECK-NEXT: [[ADD32:%.*]] = fadd reassoc nnan ninf nsz arcp afn <4 x float> [[ADD23]], [[MATRIX_ROW_INS31]]
|
||||
// CHECK-NEXT: ret <4 x float> [[ADD32]]
|
||||
//
|
||||
float4 AddFloatMatrixConstant(float4x4 M) {
|
||||
return M[0] + M[1] + M[2] + M[3];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden noundef <4 x i32> @_Z20AddIntMatrixConstantu11matrix_typeILm4ELm4EiE(
|
||||
// CHECK-SAME: <16 x i32> noundef [[M:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [16 x i32], align 4
|
||||
// CHECK-NEXT: store <16 x i32> [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <16 x i32> [[TMP0]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM1:%.*]] = extractelement <16 x i32> [[TMP0]], i32 4
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS]], i32 [[MATRIX_ELEM1]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM3:%.*]] = extractelement <16 x i32> [[TMP0]], i32 8
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS2]], i32 [[MATRIX_ELEM3]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM5:%.*]] = extractelement <16 x i32> [[TMP0]], i32 12
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS4]], i32 [[MATRIX_ELEM5]], i32 3
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM7:%.*]] = extractelement <16 x i32> [[TMP1]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS8:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM7]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM9:%.*]] = extractelement <16 x i32> [[TMP1]], i32 5
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS10:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS8]], i32 [[MATRIX_ELEM9]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM11:%.*]] = extractelement <16 x i32> [[TMP1]], i32 9
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS12:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS10]], i32 [[MATRIX_ELEM11]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM13:%.*]] = extractelement <16 x i32> [[TMP1]], i32 13
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS14:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS12]], i32 [[MATRIX_ELEM13]], i32 3
|
||||
// CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[MATRIX_ROW_INS6]], [[MATRIX_ROW_INS14]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM15:%.*]] = extractelement <16 x i32> [[TMP2]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS16:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM15]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM17:%.*]] = extractelement <16 x i32> [[TMP2]], i32 6
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS18:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS16]], i32 [[MATRIX_ELEM17]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM19:%.*]] = extractelement <16 x i32> [[TMP2]], i32 10
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS20:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS18]], i32 [[MATRIX_ELEM19]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM21:%.*]] = extractelement <16 x i32> [[TMP2]], i32 14
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS22:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS20]], i32 [[MATRIX_ELEM21]], i32 3
|
||||
// CHECK-NEXT: [[ADD23:%.*]] = add <4 x i32> [[ADD]], [[MATRIX_ROW_INS22]]
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM24:%.*]] = extractelement <16 x i32> [[TMP3]], i32 3
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS25:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM24]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM26:%.*]] = extractelement <16 x i32> [[TMP3]], i32 7
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS27:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS25]], i32 [[MATRIX_ELEM26]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM28:%.*]] = extractelement <16 x i32> [[TMP3]], i32 11
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS29:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS27]], i32 [[MATRIX_ELEM28]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM30:%.*]] = extractelement <16 x i32> [[TMP3]], i32 15
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS31:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS29]], i32 [[MATRIX_ELEM30]], i32 3
|
||||
// CHECK-NEXT: [[ADD32:%.*]] = add <4 x i32> [[ADD23]], [[MATRIX_ROW_INS31]]
|
||||
// CHECK-NEXT: ret <4 x i32> [[ADD32]]
|
||||
//
|
||||
int4 AddIntMatrixConstant(int4x4 M) {
|
||||
return M[0] + M[1] + M[2] + M[3];
|
||||
}
|
||||
@ -0,0 +1,127 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: define hidden void @_Z9setMatrixRu11matrix_typeILm4ELm4EfEiDv4_f(
|
||||
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(64) [[M:%.*]], i32 noundef [[INDEX:%.*]], <4 x float> noundef nofpclass(nan inf) [[V:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
|
||||
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <4 x float>, align 16
|
||||
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: store <4 x float> [[V]], ptr [[V_ADDR]], align 16
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[V_ADDR]], align 16
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3:![0-9]+]], !align [[META4:![0-9]+]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_LOAD:%.*]] = load <16 x float>, ptr [[TMP1]], align 4
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = add i32 0, [[TMP2]]
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP0]], i32 0
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = insertelement <16 x float> [[MATRIX_LOAD]], float [[TMP4]], i32 [[TMP3]]
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = add i32 4, [[TMP2]]
|
||||
// CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x float> [[TMP0]], i32 1
|
||||
// CHECK-NEXT: [[TMP8:%.*]] = insertelement <16 x float> [[TMP5]], float [[TMP7]], i32 [[TMP6]]
|
||||
// CHECK-NEXT: [[TMP9:%.*]] = add i32 8, [[TMP2]]
|
||||
// CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x float> [[TMP0]], i32 2
|
||||
// CHECK-NEXT: [[TMP11:%.*]] = insertelement <16 x float> [[TMP8]], float [[TMP10]], i32 [[TMP9]]
|
||||
// CHECK-NEXT: [[TMP12:%.*]] = add i32 12, [[TMP2]]
|
||||
// CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x float> [[TMP0]], i32 3
|
||||
// CHECK-NEXT: [[TMP14:%.*]] = insertelement <16 x float> [[TMP11]], float [[TMP13]], i32 [[TMP12]]
|
||||
// CHECK-NEXT: store <16 x float> [[TMP14]], ptr [[TMP1]], align 4
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void setMatrix(out float4x4 M, int index, float4 V) {
|
||||
M[index] = V;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden void @_Z15setMatrixScalarRu11matrix_typeILm2ELm1EfEif(
|
||||
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(8) [[M:%.*]], i32 noundef [[INDEX:%.*]], float noundef nofpclass(nan inf) [[S:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
|
||||
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: [[S_ADDR:%.*]] = alloca float, align 4
|
||||
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: store float [[S]], ptr [[S_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[S_ADDR]], align 4
|
||||
// CHECK-NEXT: [[SPLAT_SPLATINSERT:%.*]] = insertelement <1 x float> poison, float [[TMP0]], i64 0
|
||||
// CHECK-NEXT: [[SPLAT_SPLAT:%.*]] = shufflevector <1 x float> [[SPLAT_SPLATINSERT]], <1 x float> poison, <1 x i32> zeroinitializer
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_LOAD:%.*]] = load <2 x float>, ptr [[TMP1]], align 4
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = add i32 0, [[TMP2]]
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = extractelement <1 x float> [[SPLAT_SPLAT]], i32 0
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = insertelement <2 x float> [[MATRIX_LOAD]], float [[TMP4]], i32 [[TMP3]]
|
||||
// CHECK-NEXT: store <2 x float> [[TMP5]], ptr [[TMP1]], align 4
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void setMatrixScalar(out float2x1 M, int index, float S) {
|
||||
M[index] = S;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden void @_Z19setMatrixConstIndexRu11matrix_typeILm4ELm4EiES_(
|
||||
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(64) [[M:%.*]], <16 x i32> noundef [[N:%.*]]) #[[ATTR0]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
|
||||
// CHECK-NEXT: [[N_ADDR:%.*]] = alloca [16 x i32], align 4
|
||||
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
|
||||
// CHECK-NEXT: store <16 x i32> [[N]], ptr [[N_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[N_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <16 x i32> [[TMP0]], i32 3
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM1:%.*]] = extractelement <16 x i32> [[TMP0]], i32 7
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS]], i32 [[MATRIX_ELEM1]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM3:%.*]] = extractelement <16 x i32> [[TMP0]], i32 11
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS2]], i32 [[MATRIX_ELEM3]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM5:%.*]] = extractelement <16 x i32> [[TMP0]], i32 15
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS4]], i32 [[MATRIX_ELEM5]], i32 3
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
|
||||
// CHECK-NEXT: store <4 x i32> [[MATRIX_ROW_INS6]], ptr [[TMP1]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load <16 x i32>, ptr [[N_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM7:%.*]] = extractelement <16 x i32> [[TMP2]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS8:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM7]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM9:%.*]] = extractelement <16 x i32> [[TMP2]], i32 6
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS10:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS8]], i32 [[MATRIX_ELEM9]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM11:%.*]] = extractelement <16 x i32> [[TMP2]], i32 10
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS12:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS10]], i32 [[MATRIX_ELEM11]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM13:%.*]] = extractelement <16 x i32> [[TMP2]], i32 14
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS14:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS12]], i32 [[MATRIX_ELEM13]], i32 3
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr <16 x i32>, ptr [[TMP3]], i32 0, i32 4
|
||||
// CHECK-NEXT: store <4 x i32> [[MATRIX_ROW_INS14]], ptr [[TMP4]], align 4
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = load <16 x i32>, ptr [[N_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM15:%.*]] = extractelement <16 x i32> [[TMP5]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS16:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM15]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM17:%.*]] = extractelement <16 x i32> [[TMP5]], i32 5
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS18:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS16]], i32 [[MATRIX_ELEM17]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM19:%.*]] = extractelement <16 x i32> [[TMP5]], i32 9
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS20:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS18]], i32 [[MATRIX_ELEM19]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM21:%.*]] = extractelement <16 x i32> [[TMP5]], i32 13
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS22:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS20]], i32 [[MATRIX_ELEM21]], i32 3
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
|
||||
// CHECK-NEXT: [[TMP7:%.*]] = getelementptr <16 x i32>, ptr [[TMP6]], i32 0, i32 8
|
||||
// CHECK-NEXT: store <4 x i32> [[MATRIX_ROW_INS22]], ptr [[TMP7]], align 4
|
||||
// CHECK-NEXT: [[TMP8:%.*]] = load <16 x i32>, ptr [[N_ADDR]], align 4
|
||||
// CHECK-NEXT: [[MATRIX_ELEM23:%.*]] = extractelement <16 x i32> [[TMP8]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS24:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM23]], i32 0
|
||||
// CHECK-NEXT: [[MATRIX_ELEM25:%.*]] = extractelement <16 x i32> [[TMP8]], i32 4
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS26:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS24]], i32 [[MATRIX_ELEM25]], i32 1
|
||||
// CHECK-NEXT: [[MATRIX_ELEM27:%.*]] = extractelement <16 x i32> [[TMP8]], i32 8
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS28:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS26]], i32 [[MATRIX_ELEM27]], i32 2
|
||||
// CHECK-NEXT: [[MATRIX_ELEM29:%.*]] = extractelement <16 x i32> [[TMP8]], i32 12
|
||||
// CHECK-NEXT: [[MATRIX_ROW_INS30:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS28]], i32 [[MATRIX_ELEM29]], i32 3
|
||||
// CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
|
||||
// CHECK-NEXT: [[TMP10:%.*]] = getelementptr <16 x i32>, ptr [[TMP9]], i32 0, i32 12
|
||||
// CHECK-NEXT: store <4 x i32> [[MATRIX_ROW_INS30]], ptr [[TMP10]], align 4
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void setMatrixConstIndex(out int4x4 M, int4x4 N ) {
|
||||
M[0] = N[3];
|
||||
M[1] = N[2];
|
||||
M[2] = N[1];
|
||||
M[3] = N[0];
|
||||
}
|
||||
|
||||
//.
|
||||
// CHECK: [[META3]] = !{}
|
||||
// CHECK: [[META4]] = !{i64 4}
|
||||
//.
|
||||
12
clang/test/SemaHLSL/matrix_single_subscript_errors.hlsl
Normal file
12
clang/test/SemaHLSL/matrix_single_subscript_errors.hlsl
Normal file
@ -0,0 +1,12 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.4-library -finclude-default-header -verify %s
|
||||
|
||||
float2x3 gM;
|
||||
|
||||
void bad_index_type(float f) {
|
||||
gM[f]; // expected-error {{matrix row index is not an integer}}
|
||||
}
|
||||
|
||||
// 2 rows: valid row indices: 0, 1
|
||||
void bad_constant_row_index() {
|
||||
gM[2]; // expected-error {{matrix row index is outside the allowed range}}
|
||||
}
|
||||
@ -430,6 +430,11 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
|
||||
K = CXCursor_ArraySubscriptExpr;
|
||||
break;
|
||||
|
||||
case Stmt::MatrixSingleSubscriptExprClass:
|
||||
// TODO: add support for MatrixSingleSubscriptExpr.
|
||||
K = CXCursor_UnexposedExpr;
|
||||
break;
|
||||
|
||||
case Stmt::MatrixSubscriptExprClass:
|
||||
// TODO: add support for MatrixSubscriptExpr.
|
||||
K = CXCursor_UnexposedExpr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user