Skip to content

Commit dc8fde0

Browse files
authored
[MLIR][LLVMIR] Fix LLVM IR import of ZeroInitializers to constant zero (#171107)
Constant zero aggregate structures are imported to from llvm IR as undef. This includes for example LandingPad Instructions which have zero value filters, structs. This fixes the import to use the zeroOp to materialize a zero-initialized constant.
1 parent f40c8e7 commit dc8fde0

File tree

4 files changed

+110
-27
lines changed

4 files changed

+110
-27
lines changed

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,22 +1765,21 @@ FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
17651765
return lookupValue(inst);
17661766
}
17671767

1768+
// Convert zero-initialized aggregates to ZeroOp.
1769+
if (auto *aggregateZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1770+
Type type = convertType(aggregateZero->getType());
1771+
return ZeroOp::create(builder, loc, type).getResult();
1772+
}
1773+
17681774
// Convert aggregate constants.
1769-
if (isa<llvm::ConstantAggregate>(constant) ||
1770-
isa<llvm::ConstantAggregateZero>(constant)) {
1775+
if (auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
17711776
// Lookup the aggregate elements that have been converted before.
17721777
SmallVector<Value> elementValues;
1773-
if (auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1774-
elementValues.reserve(constAgg->getNumOperands());
1775-
for (llvm::Value *operand : constAgg->operands())
1776-
elementValues.push_back(lookupValue(operand));
1777-
}
1778-
if (auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1779-
unsigned numElements = constAgg->getElementCount().getFixedValue();
1780-
elementValues.reserve(numElements);
1781-
for (unsigned i = 0, e = numElements; i != e; ++i)
1782-
elementValues.push_back(lookupValue(constAgg->getElementValue(i)));
1783-
}
1778+
1779+
elementValues.reserve(constAgg->getNumOperands());
1780+
for (llvm::Value *operand : constAgg->operands())
1781+
elementValues.push_back(lookupValue(operand));
1782+
17841783
assert(llvm::count(elementValues, nullptr) == 0 &&
17851784
"expected all elements have been converted before");
17861785

mlir/test/Target/LLVMIR/Import/constant.ll

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,8 @@ define i32 @function_address_after_def() {
198198
%nested_agg_type = type {%simple_agg_type, ptr}
199199
@nested_agg = global %nested_agg_type { %simple_agg_type{i32 1, i8 2, i16 3, i32 4}, ptr null }
200200

201-
; CHECK-DAG: %[[NULL:.+]] = llvm.mlir.zero : !llvm.ptr
202-
; CHECK-DAG: %[[ROOT:.+]] = llvm.mlir.undef : vector<2x!llvm.ptr>
203-
; CHECK-DAG: %[[P0:.+]] = llvm.mlir.constant(0 : i32) : i32
204-
; CHECK-DAG: %[[CHAIN0:.+]] = llvm.insertelement %[[NULL]], %[[ROOT]][%[[P0]] : i32] : vector<2x!llvm.ptr>
205-
; CHECK-DAG: %[[P1:.+]] = llvm.mlir.constant(1 : i32) : i32
206-
; CHECK-DAG: %[[CHAIN1:.+]] = llvm.insertelement %[[NULL]], %[[CHAIN0]][%[[P1]] : i32] : vector<2x!llvm.ptr>
207-
; CHECK-DAG: llvm.return %[[CHAIN1]] : vector<2x!llvm.ptr>
201+
; CHECK-DAG: %[[VEC:.+]] = llvm.mlir.zero : vector<2x!llvm.ptr>
202+
; CHECK-DAG: llvm.return %[[VEC]] : vector<2x!llvm.ptr>
208203
@vector_agg = global <2 x ptr> <ptr null, ptr null>
209204

210205
; // -----
@@ -274,3 +269,42 @@ define void @call_alias_func() {
274269

275270
; CHECK-LABEL: @call_alias_func()
276271
; CHECK: llvm.dso_local_equivalent @alias_func : !llvm.ptr
272+
273+
; // -----
274+
275+
; Test that zeroinitializer for zero-element array is correctly handled
276+
277+
@global_zero_array = global [0 x ptr] zeroinitializer
278+
279+
; CHECK: llvm.mlir.global external @global_zero_array() {addr_space = 0 : i32} : !llvm.array<0 x ptr> {
280+
; CHECK: %[[ZERO:.+]] = llvm.mlir.zero : !llvm.array<0 x ptr>
281+
; CHECK: llvm.return %[[ZERO]] : !llvm.array<0 x ptr>
282+
283+
; CHECK-LABEL: @load_zero_array
284+
define [0 x ptr] @load_zero_array() {
285+
; CHECK: %[[ADDR:.+]] = llvm.mlir.addressof @global_zero_array : !llvm.ptr
286+
; CHECK: %[[VAL:.+]] = llvm.load %[[ADDR]] {{.*}}: !llvm.ptr -> !llvm.array<0 x ptr>
287+
; CHECK: llvm.return %[[VAL]] : !llvm.array<0 x ptr>
288+
%val = load [0 x ptr], ptr @global_zero_array
289+
ret [0 x ptr] %val
290+
}
291+
292+
; // -----
293+
294+
; Test that zeroinitializer for zero-element structs is correctly handled
295+
296+
@global_zero_struct = global {} zeroinitializer
297+
298+
; CHECK: llvm.mlir.global external @global_zero_struct() {addr_space = 0 : i32} : !llvm.struct<()> {
299+
; CHECK: %[[ZERO:.+]] = llvm.mlir.zero : !llvm.struct<()>
300+
; CHECK: llvm.return %[[ZERO]] : !llvm.struct<()>
301+
302+
; // -----
303+
304+
; Test that zeroinitializer for arrays with elements still works correctly.
305+
; Note that arrays with primitive types that can be represented as dense
306+
; attributes may use the attribute form directly.
307+
308+
@global_array_with_elements = global [3 x i32] zeroinitializer
309+
310+
; CHECK: llvm.mlir.global external @global_array_with_elements({{.*}}) {addr_space = 0 : i32} : !llvm.array<3 x i32>

mlir/test/Target/LLVMIR/Import/exception.ll

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,7 @@ define void @landingpad_dominance() personality ptr @__gxx_personality_v0 {
123123
entry:
124124
; CHECK: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr
125125
; CHECK: %[[c1:.*]] = llvm.mlir.constant(0 : i32) : i32
126-
; CHECK: %[[undef:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i32)>
127-
; CHECK: %[[tmpstruct:.*]] = llvm.insertvalue %[[null]], %[[undef]][0] : !llvm.struct<(ptr, i32)>
128-
; CHECK: %[[struct:.*]] = llvm.insertvalue %[[c1]], %[[tmpstruct]][1] : !llvm.struct<(ptr, i32)>
126+
; CHECK: %[[struct:.*]] = llvm.mlir.zero : !llvm.struct<(ptr, i32)>
129127
; CHECK: llvm.call @f0(%[[null]]) : (!llvm.ptr) -> ()
130128
call void @f0(ptr null)
131129
; CHECK: llvm.call @f1(%[[c1]]) : (i32) -> ()
@@ -190,3 +188,57 @@ bb3:
190188
!6 = !DILocation(line: 2, column: 2, scope: !3)
191189
!7 = !DILocation(line: 7, column: 4, scope: !4, inlinedAt: !6)
192190
!8 = !DILocalVariable(scope: !4, name: "size")
191+
192+
; // -----
193+
194+
declare i32 @__gxx_personality_v0(...)
195+
declare void @foo(ptr)
196+
197+
; Test that landingpad filter clauses with zeroinitializer are correctly
198+
; translated to llvm.mlir.zero
199+
200+
; CHECK-LABEL: @landingpad_zero_filter
201+
define void @landingpad_zero_filter() personality ptr @__gxx_personality_v0 {
202+
entry:
203+
; CHECK: %[[ZERO:.+]] = llvm.mlir.zero : !llvm.array<0 x ptr>
204+
invoke void @foo(ptr null) to label %normal unwind label %lpad
205+
206+
normal:
207+
ret void
208+
209+
lpad:
210+
; CHECK: %{{[0-9]+}} = llvm.landingpad cleanup (filter %[[ZERO]] : !llvm.array<0 x ptr>) : !llvm.struct<(ptr, i32)>
211+
%0 = landingpad { ptr, i32 }
212+
cleanup
213+
filter [0 x ptr] zeroinitializer
214+
ret void
215+
}
216+
217+
; // -----
218+
219+
declare i32 @__gxx_personality_v0(...)
220+
declare void @foo(ptr)
221+
222+
; Test that landingpad with multiple filter clauses of different zero-element
223+
; array types are correctly handled. Note that zero-element arrays of primitive
224+
; types like i32 may be converted to dense attributes, while ptr arrays use
225+
; llvm.mlir.zero.
226+
227+
; CHECK-LABEL: @landingpad_mixed_filters
228+
define void @landingpad_mixed_filters() personality ptr @__gxx_personality_v0 {
229+
entry:
230+
; CHECK: %[[ZERO1:.+]] = llvm.mlir.zero : !llvm.array<0 x ptr>
231+
; CHECK: %[[ZERO2:.+]] = llvm.mlir.{{(zero|constant)}}{{.*}}: !llvm.array<0 x i32>
232+
invoke void @foo(ptr null) to label %normal unwind label %lpad
233+
234+
normal:
235+
ret void
236+
237+
lpad:
238+
; CHECK: %{{[0-9]+}} = llvm.landingpad cleanup (filter %[[ZERO1]] : !llvm.array<0 x ptr>) (filter %[[ZERO2]] : !llvm.array<0 x i32>) : !llvm.struct<(ptr, i32)>
239+
%0 = landingpad { ptr, i32 }
240+
cleanup
241+
filter [0 x ptr] zeroinitializer
242+
filter [0 x i32] zeroinitializer
243+
ret void
244+
}

mlir/test/Target/LLVMIR/Import/zeroinitializer.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
; CHECK: llvm.mlir.global external @D()
66
; CHECK-SAME: !llvm.struct<"Domain", (ptr, ptr)>
77
; CHECK: %[[E0:.+]] = llvm.mlir.zero : !llvm.ptr
8-
; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"Domain", (ptr, ptr)>
9-
; CHECK: %[[CHAIN:.+]] = llvm.insertvalue %[[E0]], %[[ROOT]][0]
10-
; CHECK: %[[RES:.+]] = llvm.insertvalue %[[E0]], %[[CHAIN]][1]
11-
; CHECK: llvm.return %[[RES]]
8+
; CHECK: %[[RES:.+]] = llvm.mlir.zero : !llvm.struct<"Domain", (ptr, ptr)>
9+
; CHECK: llvm.return %[[RES]] : !llvm.struct<"Domain", (ptr, ptr)>
1210
@D = global %Domain zeroinitializer

0 commit comments

Comments
 (0)