Skip to content

Commit c5b8798

Browse files
committed
[mlir][vector] Fix crash in vector.from_elements folding with poison values
1 parent e8311f8 commit c5b8798

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

mlir/lib/Dialect/Vector/IR/VectorOps.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,21 @@ std::optional<int64_t> vector::getConstantVscaleMultiplier(Value value) {
398398

399399
/// Converts an IntegerAttr to have the specified type if needed.
400400
/// This handles cases where constant attributes have a different type than the
401-
/// target element type. If the input attribute is not an IntegerAttr or already
402-
/// has the correct type, returns it unchanged.
401+
/// target element type. Returns null if the attribute is poison/invalid or
402+
/// conversion fails.
403403
static Attribute convertIntegerAttr(Attribute attr, Type expectedType) {
404-
if (auto intAttr = mlir::dyn_cast<IntegerAttr>(attr)) {
405-
if (intAttr.getType() != expectedType)
406-
return IntegerAttr::get(expectedType, intAttr.getInt());
407-
}
408-
return attr;
404+
// Check for poison attributes before any casting operations
405+
if (!attr || isa<ub::PoisonAttrInterface>(attr))
406+
return {}; // Poison or invalid attribute
407+
408+
auto intAttr = mlir::dyn_cast<IntegerAttr>(attr);
409+
if (!intAttr)
410+
return attr; // Not an IntegerAttr, return unchanged (e.g., FloatAttr)
411+
412+
if (intAttr.getType() == expectedType)
413+
return attr; // Already correct type
414+
415+
return IntegerAttr::get(expectedType, intAttr.getInt());
409416
}
410417

411418
//===----------------------------------------------------------------------===//
@@ -2478,6 +2485,12 @@ static OpFoldResult foldFromElementsToConstant(FromElementsOp fromElementsOp,
24782485
return convertIntegerAttr(attr, destEltType);
24792486
});
24802487

2488+
// Check if any attributes are poison/invalid (indicated by null attributes).
2489+
// Note: convertIntegerAttr returns valid non-integer attributes unchanged,
2490+
// only returns null for poison/invalid attributes.
2491+
if (llvm::any_of(convertedElements, [](Attribute attr) { return !attr; }))
2492+
return {};
2493+
24812494
return DenseElementsAttr::get(destVecType, convertedElements);
24822495
}
24832496

mlir/test/Dialect/Vector/canonicalize.mlir

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3375,6 +3375,17 @@ func.func @negative_from_elements_to_constant() -> vector<1x!llvm.ptr> {
33753375
return %b : vector<1x!llvm.ptr>
33763376
}
33773377

3378+
// -----
3379+
3380+
// CHECK-LABEL: @from_elements_poison
3381+
// CHECK: %[[VAL:.*]] = ub.poison : vector<2xf32>
3382+
// CHECK: return %[[VAL]] : vector<2xf32>
3383+
func.func @from_elements_poison() -> vector<2xf32> {
3384+
%0 = ub.poison : f32
3385+
%1 = vector.from_elements %0, %0 : vector<2xf32>
3386+
return %1 : vector<2xf32>
3387+
}
3388+
33783389
// +---------------------------------------------------------------------------
33793390
// End of Tests for foldFromElementsToConstant
33803391
// +---------------------------------------------------------------------------

0 commit comments

Comments
 (0)