Skip to content

Commit c6ac7e9

Browse files
committed
[mlir][llvm] Add MD_prof import error handling
This commit adds additional checks and warning messages to the MD_prof import. As LLVM does not verify most metadata, the import has the be resilient towards ill-formatted inputs. Reviewed By: gysit Differential Revision: https://reviews.llvm.org/D143492
1 parent 40ffe9c commit c6ac7e9

File tree

2 files changed

+148
-12
lines changed

2 files changed

+148
-12
lines changed

mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,36 +84,48 @@ static LogicalResult setProfilingAttr(OpBuilder &builder, llvm::MDNode *node,
8484
LLVM::ModuleImport &moduleImport) {
8585
// Return success for empty metadata nodes since there is nothing to import.
8686
if (!node->getNumOperands())
87-
return success();
87+
return op->emitWarning() << "expected non-empty profiling metadata node";
8888

8989
auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
9090
if (!name)
91-
return failure();
91+
return op->emitWarning()
92+
<< "expected profiling metadata node to have a string identifier";
9293

9394
// Handle function entry count metadata.
9495
if (name->getString().equals("function_entry_count")) {
96+
auto emitNodeWarning = [&]() {
97+
return op->emitWarning()
98+
<< "expected function_entry_count to hold a single i64 value";
99+
};
100+
95101
// TODO support function entry count metadata with GUID fields.
96102
if (node->getNumOperands() != 2)
97-
return failure();
103+
return emitNodeWarning();
98104

99105
llvm::ConstantInt *entryCount =
100-
llvm::mdconst::extract<llvm::ConstantInt>(node->getOperand(1));
106+
llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(1));
107+
if (!entryCount)
108+
return emitNodeWarning();
101109
if (auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
102110
funcOp.setFunctionEntryCount(entryCount->getZExtValue());
103111
return success();
104112
}
105-
return failure();
113+
return op->emitWarning()
114+
<< "expected function_entry_count to be attached to a function";
106115
}
107116

108117
if (!name->getString().equals("branch_weights"))
109-
return failure();
118+
return op->emitWarning()
119+
<< "unknown profiling metadata node " << name->getString();
110120

111121
// Handle branch weights metadata.
112122
SmallVector<int32_t> branchWeights;
113123
branchWeights.reserve(node->getNumOperands() - 1);
114124
for (unsigned i = 1, e = node->getNumOperands(); i != e; ++i) {
115125
llvm::ConstantInt *branchWeight =
116-
llvm::mdconst::extract<llvm::ConstantInt>(node->getOperand(i));
126+
llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(i));
127+
if (!branchWeight)
128+
return op->emitWarning() << "expected branch weights to be integers";
117129
branchWeights.push_back(branchWeight->getZExtValue());
118130
}
119131

@@ -124,7 +136,10 @@ static LogicalResult setProfilingAttr(OpBuilder &builder, llvm::MDNode *node,
124136
builder.getI32VectorAttr(branchWeights));
125137
return success();
126138
})
127-
.Default([](auto) { return failure(); });
139+
.Default([op](auto) {
140+
return op->emitWarning()
141+
<< op->getName() << " does not support branch weights";
142+
});
128143
}
129144

130145
/// Searches the symbol reference pointing to the metadata operation that

mlir/test/Target/LLVMIR/Import/import-failure.ll

Lines changed: 125 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ define void @unhandled_intrinsic(ptr %arg1, ptr %arg2) {
5656

5757
; // -----
5858

59-
; CHECK: import-failure.ll
60-
; CHECK-SAME: warning: unhandled metadata: !0 = !{!"unknown metadata"} on br i1 %arg1, label %bb1, label %bb2, !prof !0
59+
; CHECK: warning: unhandled metadata: !0 = !{!"unknown metadata"} on br i1 %arg1, label %bb1, label %bb2, !prof !0
6160
define i64 @unhandled_metadata(i1 %arg1, i64 %arg2) {
6261
entry:
6362
br i1 %arg1, label %bb1, label %bb2, !prof !0
@@ -71,8 +70,7 @@ bb2:
7170

7271
; // -----
7372

74-
; CHECK: import-failure.ll
75-
; CHECK-SAME: warning: unhandled function metadata: !0 = !{!"unknown metadata"} on define void @unhandled_func_metadata(i1 %arg1, i64 %arg2) !prof !0
73+
; CHECK: warning: unhandled function metadata: !0 = !{!"unknown metadata"} on define void @unhandled_func_metadata(i1 %arg1, i64 %arg2) !prof !0
7674
define void @unhandled_func_metadata(i1 %arg1, i64 %arg2) !prof !0 {
7775
ret void
7876
}
@@ -439,3 +437,126 @@ end:
439437
!0 = distinct !{!0, !1, !2}
440438
!1 = !{!"llvm.loop.disable_nonforced"}
441439
!2 = !{!"llvm.loop.typo"}
440+
441+
; // -----
442+
443+
; CHECK: import-failure.ll
444+
; CHECK-SAME: warning: expected non-empty profiling metadata node
445+
; CHECK: warning: unhandled metadata: !0 = !{}
446+
define void @cond_br(i1 %arg) {
447+
entry:
448+
br i1 %arg, label %bb1, label %bb2, !prof !0
449+
bb1:
450+
ret void
451+
bb2:
452+
ret void
453+
}
454+
455+
!0 = !{}
456+
457+
; // -----
458+
459+
; CHECK: import-failure.ll
460+
; CHECK-SAME: warning: expected profiling metadata node to have a string identifier
461+
; CHECK: import-failure.ll:{{.*}} warning: unhandled metadata: !0 = !{i32 64}
462+
define void @cond_br(i1 %arg) {
463+
entry:
464+
br i1 %arg, label %bb1, label %bb2, !prof !0
465+
bb1:
466+
ret void
467+
bb2:
468+
ret void
469+
}
470+
471+
!0 = !{i32 64}
472+
473+
; // -----
474+
475+
; CHECK: import-failure.ll
476+
; CHECK-SAME: warning: expected function_entry_count to hold a single i64 value
477+
; CHECK: warning: unhandled function metadata: !0 = !{!"function_entry_count"}
478+
define void @cond_br(i1 %arg) !prof !0 {
479+
entry:
480+
br i1 %arg, label %bb1, label %bb2
481+
bb1:
482+
ret void
483+
bb2:
484+
ret void
485+
}
486+
487+
!0 = !{!"function_entry_count"}
488+
489+
; // -----
490+
491+
; CHECK: import-failure.ll
492+
; CHECK-SAME: warning: expected function_entry_count to hold a single i64 value
493+
; CHECK: warning: unhandled function metadata: !0 = !{!"function_entry_count", !"string"}
494+
define void @cond_br(i1 %arg) !prof !0 {
495+
entry:
496+
br i1 %arg, label %bb1, label %bb2
497+
bb1:
498+
ret void
499+
bb2:
500+
ret void
501+
}
502+
503+
!0 = !{!"function_entry_count", !"string"}
504+
505+
; // -----
506+
507+
; CHECK: import-failure.ll
508+
; CHECK-SAME: warning: expected function_entry_count to be attached to a function
509+
; CHECK: warning: unhandled metadata: !0 = !{!"function_entry_count", i64 42}
510+
define void @cond_br(i1 %arg) {
511+
entry:
512+
br i1 %arg, label %bb1, label %bb2, !prof !0
513+
bb1:
514+
ret void
515+
bb2:
516+
ret void
517+
}
518+
519+
!0 = !{!"function_entry_count", i64 42}
520+
521+
; // -----
522+
523+
; CHECK: import-failure.ll
524+
; CHECK-SAME: warning: unknown profiling metadata node unknown_prof_type
525+
; CHECK: warning: unhandled metadata: !0 = !{!"unknown_prof_type"}
526+
define void @cond_br(i1 %arg) {
527+
entry:
528+
br i1 %arg, label %bb1, label %bb2, !prof !0
529+
bb1:
530+
ret void
531+
bb2:
532+
ret void
533+
}
534+
535+
!0 = !{!"unknown_prof_type"}
536+
537+
; // -----
538+
539+
; CHECK: import-failure.ll
540+
; CHECK-SAME: warning: expected branch weights to be integers
541+
; CHECK: warning: unhandled metadata: !0 = !{!"branch_weights", !"foo"}
542+
define void @cond_br(i1 %arg) {
543+
entry:
544+
br i1 %arg, label %bb1, label %bb2, !prof !0
545+
bb1:
546+
ret void
547+
bb2:
548+
ret void
549+
}
550+
551+
!0 = !{!"branch_weights", !"foo"}
552+
553+
; // -----
554+
555+
; CHECK: import-failure.ll
556+
; CHECK-SAME: warning: llvm.func does not support branch weights
557+
; CHECK: import-failure.ll:{{.*}} warning: unhandled function metadata: !0 = !{!"branch_weights", i32 64}
558+
define void @cond_br(i1 %arg) !prof !0 {
559+
ret void
560+
}
561+
562+
!0 = !{!"branch_weights", i32 64}

0 commit comments

Comments
 (0)