## Problem `RemoveDeadValues` can legally drop dead function arguments on private `func.func` callees. But call-sites to such functions aren't fixed if the call operation keeps its call arguments in a **segmented operand group** (i.ie, uses `AttrSizedOperandSegments`), unless the call op implements `getArgOperandsMutable` and the RDV pass actually uses it. ## Fix When RDV decides to drop callee function args, it should, for each call-site that implements `CallOpInterface`, **shrink the call's argument segment** via `getArgOperandsMutable()` using the same dead-arg indices. This keeps both the flat operand list and the `operand_segment_sizes` attribute in sync (that's what `MutableOperandRange` does when bound to the segment). ## Note This change is a no-op for: * call ops without segment operands (they still get their flat operands erased via the generic path) * call ops whose calle args weren't dropped (public, external, non-`func-func`, unresolved symbol, etc) * `llvm.call`/`llvm.invoke` (RDV doesn't drop `llvm.func` args --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
24 lines
794 B
MLIR
24 lines
794 B
MLIR
// RUN: mlir-opt --split-input-file --remove-dead-values --mlir-print-op-generic %s | FileCheck %s --check-prefix=GEN
|
|
|
|
// -----
|
|
// Private callee: both args become dead after internal DCE; RDV drops callee
|
|
// args and shrinks the *args* segment on the call-site to zero; sizes kept in
|
|
// sync.
|
|
|
|
module {
|
|
func.func private @callee(%x: i32, %y: i32) {
|
|
%u = arith.addi %x, %x : i32 // %y is dead
|
|
return
|
|
}
|
|
|
|
func.func @caller(%a: i32, %b: i32) {
|
|
// args segment initially has 2 operands.
|
|
"test.call_with_segments"(%a, %b) { callee = @callee,
|
|
operandSegmentSizes = array<i32: 0, 2, 0> } : (i32, i32) -> ()
|
|
return
|
|
}
|
|
}
|
|
|
|
// GEN: "test.call_with_segments"() <{callee = @callee, operandSegmentSizes = array<i32: 0, 0, 0>}> : () -> ()
|
|
// ^ args shrank from 2 -> 0
|