diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp index 7875fa9d43d9e22484da25cf2b06bc6bb1202dc9..e99fd8f9b9e106ebd71581d6c2ddfc5e11ddb325 100644 --- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp +++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp @@ -72,7 +72,7 @@ void LivenessAnalysis::visitOperation(Operation *op, ArrayRef operands, ArrayRef results) { // This marks values of type (1.a) liveness as "live". - if (!isMemoryEffectFree(op)) { + if (!isMemoryEffectFree(op) || op->hasTrait()) { for (auto *operand : operands) propagateIfChanged(operand, operand->markLive()); } diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir index 69426fdb6208329e9b1e1ffecd371d1a56eafc19..447325ff2bd77c29d3c1b6a963d2491ffe559268 100644 --- a/mlir/test/Transforms/remove-dead-values.mlir +++ b/mlir/test/Transforms/remove-dead-values.mlir @@ -357,3 +357,26 @@ func.func @kernel(%arg0: memref<18xf32>) { // CHECK: gpu.launch blocks // CHECK: memref.store // CHECK-NEXT: gpu.terminator + +// ----- + +// Check that yielded values aren't incorrectly removed in linalg regions +module { + func.func @linalg_red_add(%arg0: tensor, %arg1: tensor<1xf32>) -> tensor<1xf32> { + %0 = linalg.generic { + indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> (0)>], + iterator_types = ["reduction"] + } ins(%arg0 : tensor) outs(%arg1 : tensor<1xf32>) { + ^bb0(%in: f32, %out: f32): + %1 = arith.addf %in, %out : f32 + %2 = arith.subf %1, %out : f32 // this should still be removed + linalg.yield %1 : f32 + } -> tensor<1xf32> + return %0 : tensor<1xf32> + } +} + +// CHECK-LABEL: func @linalg_red_add +// CHECK: %[[yield:.*]] = arith.addf %{{.*}}, %{{.*}} : f32 +// CHECK: linalg.yield %[[yield]] : f32 +// CHECK-NOT: arith.subf