Skip to content

Commit 1563cfe

Browse files
committed
FPInfo: MachineVerifier
FPInfo: MachineIRBuilder assertions
1 parent 0e651e6 commit 1563cfe

File tree

3 files changed

+235
-61
lines changed

3 files changed

+235
-61
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class MachineIRBuilder {
239239
unsigned getOpcodeForMerge(const DstOp &DstOp, ArrayRef<SrcOp> SrcOps) const;
240240

241241
protected:
242-
void validateTruncExt(const LLT Dst, const LLT Src, bool IsExtend);
242+
void validateTruncExt(const LLT Dst, const LLT Src, unsigned Opc);
243243

244244
void validateUnaryOp(const LLT Res, const LLT Op0);
245245
void validateBinaryOp(const LLT Res, const LLT Op0, const LLT Op1);

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 95 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ void MachineIRBuilder::validateBinaryOp(const LLT Res, const LLT Op0,
194194

195195
void MachineIRBuilder::validateShiftOp(const LLT Res, const LLT Op0,
196196
const LLT Op1) {
197-
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
197+
assert((Res.isInteger() || Res.isIntegerVector()) && "invalid operand type");
198198
assert((Res == Op0) && "type mismatch");
199199
}
200200

@@ -203,7 +203,8 @@ MachineIRBuilder::buildPtrAdd(const DstOp &Res, const SrcOp &Op0,
203203
const SrcOp &Op1, std::optional<unsigned> Flags) {
204204
assert(Res.getLLTTy(*getMRI()).isPointerOrPointerVector() &&
205205
Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch");
206-
assert(Op1.getLLTTy(*getMRI()).getScalarType().isScalar() && "invalid offset type");
206+
assert(Op1.getLLTTy(*getMRI()).getScalarType().isInteger() &&
207+
"invalid offset type");
207208

208209
return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1}, Flags);
209210
}
@@ -228,7 +229,7 @@ MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res,
228229
const SrcOp &Op0,
229230
uint32_t NumBits) {
230231
LLT PtrTy = Res.getLLTTy(*getMRI());
231-
LLT MaskTy = LLT::scalar(PtrTy.getSizeInBits());
232+
LLT MaskTy = LLT::integer(PtrTy.getSizeInBits());
232233
Register MaskReg = getMRI()->createGenericVirtualRegister(MaskTy);
233234
buildConstant(MaskReg, maskTrailingZeros<uint64_t>(NumBits));
234235
return buildPtrMask(Res, Op0, MaskReg);
@@ -355,7 +356,7 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
355356
== EltTy.getSizeInBits() &&
356357
"creating fconstant with the wrong size");
357358

358-
assert(!Ty.isPointer() && "invalid operand type");
359+
assert((Ty.isFloat() || Ty.isFloatVector()) && "invalid operand type");
359360

360361
assert(!Ty.isScalableVector() &&
361362
"unexpected scalable vector in buildFConstant");
@@ -412,7 +413,7 @@ MachineIRBuilder::buildConstantPtrAuth(const DstOp &Res,
412413

413414
MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
414415
MachineBasicBlock &Dest) {
415-
assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
416+
assert(Tst.getLLTTy(*getMRI()).isInteger() && "invalid operand type");
416417

417418
auto MIB = buildInstr(TargetOpcode::G_BRCOND);
418419
Tst.addSrcToMIB(MIB);
@@ -459,7 +460,7 @@ MachineInstrBuilder MachineIRBuilder::buildLoadFromOffset(
459460
return buildLoad(Dst, BasePtr, *OffsetMMO);
460461

461462
LLT PtrTy = BasePtr.getLLTTy(*getMRI());
462-
LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
463+
LLT OffsetTy = LLT::integer(PtrTy.getSizeInBits());
463464
auto ConstOffset = buildConstant(OffsetTy, Offset);
464465
auto Ptr = buildPtrAdd(PtrTy, BasePtr, ConstOffset);
465466
return buildLoad(Dst, Ptr, *OffsetMMO);
@@ -550,10 +551,10 @@ MachineInstrBuilder MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc,
550551
assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
551552
TargetOpcode::G_SEXT == ExtOpc) &&
552553
"Expecting Extending Opc");
553-
assert(Res.getLLTTy(*getMRI()).isScalar() ||
554-
Res.getLLTTy(*getMRI()).isVector());
555-
assert(Res.getLLTTy(*getMRI()).isScalar() ==
556-
Op.getLLTTy(*getMRI()).isScalar());
554+
assert(Res.getLLTTy(*getMRI()).isInteger() ||
555+
Res.getLLTTy(*getMRI()).isIntegerVector());
556+
assert(Res.getLLTTy(*getMRI()).isInteger() ==
557+
Op.getLLTTy(*getMRI()).isInteger());
557558

558559
unsigned Opcode = TargetOpcode::COPY;
559560
if (Res.getLLTTy(*getMRI()).getSizeInBits() >
@@ -1185,8 +1186,11 @@ MachineIRBuilder::buildBlockAddress(Register Res, const BlockAddress *BA) {
11851186
}
11861187

11871188
void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy,
1188-
bool IsExtend) {
1189+
unsigned Opc) {
11891190
#ifndef NDEBUG
1191+
bool IsExtend = Opc == TargetOpcode::G_SEXT || Opc == TargetOpcode::G_ZEXT ||
1192+
Opc == TargetOpcode::G_ANYEXT || Opc == TargetOpcode::G_FPEXT;
1193+
bool IsFP = Opc == TargetOpcode::G_FPEXT || Opc == TargetOpcode::G_FPTRUNC;
11901194
if (DstTy.isVector()) {
11911195
assert(SrcTy.isVector() && "mismatched cast between vector and non-vector");
11921196
assert(SrcTy.getElementCount() == DstTy.getElementCount() &&
@@ -1200,6 +1204,18 @@ void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy,
12001204
else
12011205
assert(TypeSize::isKnownLT(DstTy.getSizeInBits(), SrcTy.getSizeInBits()) &&
12021206
"invalid widening trunc");
1207+
1208+
if (IsFP) {
1209+
assert(DstTy.getScalarType().isFloat() &&
1210+
"fpext/fptrunc destinaton type must be float");
1211+
assert(SrcTy.getScalarType().isFloat() &&
1212+
"fpext/fptrunc source type must be float");
1213+
} else {
1214+
assert(!DstTy.getScalarType().isFloat() &&
1215+
"ext/trunc destinaton type must not be float");
1216+
assert(!SrcTy.getScalarType().isFloat() &&
1217+
"ext/trunc source type must not be float");
1218+
}
12031219
#endif
12041220
}
12051221

@@ -1261,11 +1277,16 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
12611277
case TargetOpcode::G_USUBSAT:
12621278
case TargetOpcode::G_SSUBSAT: {
12631279
// All these are binary ops.
1280+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1281+
LLT Src1Ty = SrcOps[0].getLLTTy(*getMRI());
1282+
LLT Src2Ty = SrcOps[1].getLLTTy(*getMRI());
1283+
assert(DstTy.getScalarType().isInteger() && "Invalid destination type");
1284+
assert((Src1Ty.getScalarType().isInteger() ||
1285+
Src2Ty.getScalarType().isIntegerVector()) &&
1286+
"Invalid source type");
12641287
assert(DstOps.size() == 1 && "Invalid Dst");
12651288
assert(SrcOps.size() == 2 && "Invalid Srcs");
1266-
validateBinaryOp(DstOps[0].getLLTTy(*getMRI()),
1267-
SrcOps[0].getLLTTy(*getMRI()),
1268-
SrcOps[1].getLLTTy(*getMRI()));
1289+
validateBinaryOp(DstTy, Src1Ty, Src2Ty);
12691290
break;
12701291
}
12711292
case TargetOpcode::G_SHL:
@@ -1283,17 +1304,13 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
12831304
case TargetOpcode::G_SEXT:
12841305
case TargetOpcode::G_ZEXT:
12851306
case TargetOpcode::G_ANYEXT:
1286-
assert(DstOps.size() == 1 && "Invalid Dst");
1287-
assert(SrcOps.size() == 1 && "Invalid Srcs");
1288-
validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
1289-
SrcOps[0].getLLTTy(*getMRI()), true);
1290-
break;
1307+
case TargetOpcode::G_FPEXT:
12911308
case TargetOpcode::G_TRUNC:
12921309
case TargetOpcode::G_FPTRUNC: {
12931310
assert(DstOps.size() == 1 && "Invalid Dst");
12941311
assert(SrcOps.size() == 1 && "Invalid Srcs");
12951312
validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
1296-
SrcOps[0].getLLTTy(*getMRI()), false);
1313+
SrcOps[0].getLLTTy(*getMRI()), Opc);
12971314
break;
12981315
}
12991316
case TargetOpcode::G_BITCAST: {
@@ -1323,47 +1340,88 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
13231340
}() && "Invalid predicate");
13241341
assert(SrcOps[1].getLLTTy(*getMRI()) == SrcOps[2].getLLTTy(*getMRI()) &&
13251342
"Type mismatch");
1343+
LLT Op0Ty = SrcOps[1].getLLTTy(*getMRI());
1344+
LLT Op1Ty = SrcOps[2].getLLTTy(*getMRI());
1345+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
13261346
assert([&]() -> bool {
1327-
LLT Op0Ty = SrcOps[1].getLLTTy(*getMRI());
1328-
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
13291347
if (Op0Ty.isScalar() || Op0Ty.isPointer())
13301348
return DstTy.isScalar();
13311349
else
13321350
return DstTy.isVector() &&
13331351
DstTy.getElementCount() == Op0Ty.getElementCount();
13341352
}() && "Type Mismatch");
1353+
1354+
if (Opc == TargetOpcode::G_ICMP) {
1355+
assert(!Op0Ty.getScalarType().isFloat() &&
1356+
!Op1Ty.getScalarType().isFloat() &&
1357+
"G_ICMP operands cannot be float");
1358+
} else {
1359+
assert(Op0Ty.getScalarType().isFloat() &&
1360+
Op1Ty.getScalarType().isFloat() &&
1361+
"G_FCMP operands must be float");
1362+
}
13351363
break;
13361364
}
13371365
case TargetOpcode::G_UNMERGE_VALUES: {
13381366
assert(!DstOps.empty() && "Invalid trivial sequence");
13391367
assert(SrcOps.size() == 1 && "Invalid src for Unmerge");
1368+
1369+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1370+
LLT SrcTy = SrcOps[0].getLLTTy(*getMRI());
1371+
unsigned NumDsts = DstOps.size();
13401372
assert(llvm::all_of(DstOps,
13411373
[&, this](const DstOp &Op) {
1342-
return Op.getLLTTy(*getMRI()) ==
1343-
DstOps[0].getLLTTy(*getMRI());
1374+
return Op.getLLTTy(*getMRI()) == DstTy;
13441375
}) &&
13451376
"type mismatch in output list");
1346-
assert((TypeSize::ScalarTy)DstOps.size() *
1347-
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1348-
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1377+
assert(NumDsts * DstTy.getSizeInBits() == SrcTy.getSizeInBits() &&
13491378
"input operands do not cover output register");
1379+
1380+
if (DstTy.isVector()) {
1381+
assert(SrcTy.isVector() && "G_UNMERGE_VALUES source operand does not "
1382+
"match vector destination operands");
1383+
assert(SrcTy.getScalarType() == DstTy.getScalarType() ||
1384+
SrcTy.isPointerVector() ||
1385+
SrcTy.getSizeInBits() == NumDsts * DstTy.getSizeInBits() &&
1386+
"G_UNMERGE_VALUES source operand does "
1387+
"not match vector destination operands");
1388+
} else if (SrcTy.isFloatVector()) {
1389+
assert(DstTy.isFloat() &&
1390+
"G_UNMERGE_VALUES source vector element type does not match "
1391+
"scalar destination type");
1392+
1393+
assert(NumDsts == SrcTy.getNumElements() &&
1394+
"G_UNMERGE_VALUES number of destination operands has to match "
1395+
"the number of vector elements for float vectors");
1396+
} else {
1397+
assert(!SrcTy.isFloat() && !DstTy.isFloat() &&
1398+
"G_UNMERGE_VALUES is not supported for scalar float operands");
1399+
}
1400+
13501401
break;
13511402
}
13521403
case TargetOpcode::G_MERGE_VALUES: {
13531404
assert(SrcOps.size() >= 2 && "invalid trivial sequence");
13541405
assert(DstOps.size() == 1 && "Invalid Dst");
1406+
unsigned NumSrcs = SrcOps.size();
1407+
LLT SrcTy = SrcOps[0].getLLTTy(*getMRI());
13551408
assert(llvm::all_of(SrcOps,
13561409
[&, this](const SrcOp &Op) {
1357-
return Op.getLLTTy(*getMRI()) ==
1358-
SrcOps[0].getLLTTy(*getMRI());
1410+
return Op.getLLTTy(*getMRI()) == SrcTy;
13591411
}) &&
13601412
"type mismatch in input list");
1361-
assert((TypeSize::ScalarTy)SrcOps.size() *
1362-
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1363-
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1413+
assert(llvm::all_of(SrcOps,
1414+
[&, this](const SrcOp &Op) {
1415+
return !Op.getLLTTy(*getMRI()).isFloat();
1416+
}) &&
1417+
"float types are not alowed in input list");
1418+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1419+
assert(NumSrcs * SrcTy.getSizeInBits() == DstTy.getSizeInBits() &&
13641420
"input operands do not cover output register");
1365-
assert(!DstOps[0].getLLTTy(*getMRI()).isVector() &&
1421+
assert(!DstTy.isVector() &&
13661422
"vectors should be built with G_CONCAT_VECTOR or G_BUILD_VECTOR");
1423+
assert(!DstTy.isFloat() &&
1424+
"G_MERGE_VALUES float result types are not allowed");
13671425
break;
13681426
}
13691427
case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
@@ -1415,8 +1473,10 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
14151473
assert((!SrcOps.empty() || SrcOps.size() < 2) &&
14161474
"Must have at least 2 operands");
14171475
assert(DstOps.size() == 1 && "Invalid DstOps");
1418-
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
1419-
"Res type must be a vector");
1476+
assert(DstOps[0].getLLTTy(*getMRI()).isIntegerVector() &&
1477+
"Res type must be a vector of integers");
1478+
assert(SrcOps[0].getLLTTy(*getMRI()).isInteger() &&
1479+
"Src type must be an integer");
14201480
assert(llvm::all_of(SrcOps,
14211481
[&, this](const SrcOp &Op) {
14221482
return Op.getLLTTy(*getMRI()) ==

0 commit comments

Comments
 (0)