Skip to content

Commit

Permalink
Bump LLVM to 289b17635958d986b74683c932df6b1d12f37b70.
Browse files Browse the repository at this point in the history
This picked up a few breaking changes.

llvm/llvm-project@327d6270

This added new required methods to CallOpInterface and
CallableOpInterface. These methods are related to arrays of dictionary
attributes for each argument and result, and are normally implemented
upstream by simply defining the right arg_attrs and res_attrs
arguments on the operations. This allows some of the common utilities
upstream to work with the attributes.

However, we seem to have actually moved away from arrays of
per-argument or per-result attributes in most cases, and handle this
ourselves when we want to. I opted to stub out the methods in the
tablegen definitions of our operations, rather than adding optional
attributes and setting them to null in builders and builder callsites
like was done upstream.

There were also some accompanying name changes to a couple helper
functions, which we were able to simply apply without needing to add
new optional attributes everywhere.

llvm/llvm-project@e84f6b6a

This updated several LLVM dialect helper functions related to
lookupOrCreateFn to return FailureOr<LLVM::LLVMFuncOp>. In most cases,
we simply check for the error case and return it or signal pass
failure. There was one function in the SMT to Z3 conversion that
assumes this always succeeds and in this function I made an assertion
rather than changing the function to also potentially return failure.

llvm/llvm-project@f4e3b878

Looks like upstream is simply moving from undef to poison in many
cases, so this required us to update one test case.
  • Loading branch information
mikeurbach committed Feb 12, 2025
1 parent 2b25325 commit f6559a2
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 23 deletions.
30 changes: 30 additions & 0 deletions include/circt/Dialect/Arc/ArcOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,16 @@ def StateOp : ArcOp<"state", [
void setCalleeFromCallable(mlir::CallInterfaceCallable callee) {
(*this)->setAttr(getArcAttrName(), llvm::cast<mlir::SymbolRefAttr>(callee));
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
}

Expand Down Expand Up @@ -278,6 +288,16 @@ def CallOp : ArcOp<"call", [
void setCalleeFromCallable(mlir::CallInterfaceCallable callee) {
(*this)->setAttr(getArcAttrName(), llvm::cast<mlir::SymbolRefAttr>(callee));
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
}

Expand Down Expand Up @@ -367,6 +387,16 @@ def MemoryWritePortOp : ArcOp<"memory_write_port", [
void setCalleeFromCallable(mlir::CallInterfaceCallable callee) {
(*this)->setAttr(getArcAttrName(), llvm::cast<mlir::SymbolRefAttr>(callee));
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
}

Expand Down
19 changes: 19 additions & 0 deletions include/circt/Dialect/Handshake/HandshakeOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ def ESIInstanceOp : Op<Handshake_Dialect, "esi_instance", [
MutableOperandRange getArgOperandsMutable() {
return getOpOperandsMutable();
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
}

Expand Down Expand Up @@ -263,6 +273,15 @@ def InstanceOp : Handshake_Op<"instance", [
return getOpOperandsMutable();
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];

let assemblyFormat = [{
Expand Down
10 changes: 10 additions & 0 deletions include/circt/Dialect/Kanagawa/KanagawaOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,16 @@ def CallOp : KanagawaOp<"call", [

/// Return the callee of this operation.
MethodOp getTarget(const hw::InnerRefNamespace &symbolTable);

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];

let assemblyFormat = [{
Expand Down
20 changes: 20 additions & 0 deletions include/circt/Dialect/SV/SVStatements.td
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,16 @@ def FuncOp : SVOp<"func",
void getAsmBlockArgumentNames(mlir::Region &region,
mlir::OpAsmSetValueNameFn setNameFn);
SmallVector<hw::PortInfo> getPortList(bool excludeExplicitReturn);

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
let extraClassDefinition = [{
hw::ModuleType $cppClass::getHWModuleType() {
Expand Down Expand Up @@ -1066,6 +1076,16 @@ class SVFuncCallBase<string mnemonic, list<Trait> traits = []>: SVOp<mnemonic,
void setCalleeFromCallable(mlir::CallInterfaceCallable callee) {
(*this)->setAttr(getCalleeAttrName(), llvm::cast<mlir::SymbolRefAttr>(callee));
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
}

Expand Down
20 changes: 20 additions & 0 deletions include/circt/Dialect/Sim/SimOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ def DPIFuncOp : SimOp<"func.dpi",
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }

::mlir::Region *getCallableRegion() { return nullptr; }

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];
}

Expand Down Expand Up @@ -145,6 +155,16 @@ def DPICallOp : SimOp<"func.dpi.call",
void setCalleeFromCallable(mlir::CallInterfaceCallable callee) {
(*this)->setAttr(getCalleeAttrName(), llvm::cast<mlir::SymbolRefAttr>(callee));
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];

}
Expand Down
18 changes: 18 additions & 0 deletions include/circt/Dialect/SystemC/SystemCStatements.td
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ def CallIndirectOp : SystemCOp<"cpp.call_indirect", [
abort();
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];

let assemblyFormat = [{
Expand Down Expand Up @@ -364,6 +373,15 @@ def CallOp : SystemCOp<"cpp.call", [
(*this)->setAttr(getCalleeAttrName(), llvm::cast<mlir::SymbolRefAttr>(callee));
}

/// Stub implementations for ArgumentAttributesMethods. If desired,
/// implement these by defining arg_attrs and res_attrs as arguments to the
/// operation as OptionalAttr<DictArrayAttr>.
mlir::ArrayAttr getArgAttrsAttr() { return nullptr; }
mlir::ArrayAttr getResAttrsAttr() { return nullptr; }
void setArgAttrsAttr(mlir::ArrayAttr args) {}
void setResAttrsAttr(mlir::ArrayAttr args) {}
mlir::Attribute removeArgAttrsAttr() { return nullptr; }
mlir::Attribute removeResAttrsAttr() { return nullptr; }
}];

let assemblyFormat = [{
Expand Down
2 changes: 1 addition & 1 deletion integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set(CIRCT_INTEGRATION_TEST_DEPENDS
)

if (MLIR_ENABLE_EXECUTION_ENGINE)
list(APPEND CIRCT_INTEGRATION_TEST_DEPENDS mlir-cpu-runner)
list(APPEND CIRCT_INTEGRATION_TEST_DEPENDS mlir-runner)
endif()

# If Python bindings are available to build then enable the tests.
Expand Down
23 changes: 15 additions & 8 deletions lib/Conversion/ArcToLLVM/LowerArcToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,17 +381,22 @@ struct SimInstantiateOpLowering
// sizeof(size_t) on the target architecture.
Type convertedIndex = typeConverter->convertType(rewriter.getIndexType());

LLVM::LLVMFuncOp mallocFunc =
FailureOr<LLVM::LLVMFuncOp> mallocFunc =
LLVM::lookupOrCreateMallocFn(moduleOp, convertedIndex);
LLVM::LLVMFuncOp freeFunc = LLVM::lookupOrCreateFreeFn(moduleOp);
if (failed(mallocFunc))
return mallocFunc;

FailureOr<LLVM::LLVMFuncOp> freeFunc = LLVM::lookupOrCreateFreeFn(moduleOp);
if (failed(freeFunc))
return freeFunc;

Location loc = op.getLoc();
Value numStateBytes = rewriter.create<LLVM::ConstantOp>(
loc, convertedIndex, model.numStateBytes);
Value allocated =
rewriter
.create<LLVM::CallOp>(loc, mallocFunc, ValueRange{numStateBytes})
.getResult();
Value allocated = rewriter
.create<LLVM::CallOp>(loc, mallocFunc.value(),
ValueRange{numStateBytes})
.getResult();
Value zero =
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI8Type(), 0);
rewriter.create<LLVM::MemsetOp>(loc, allocated, zero, numStateBytes, false);
Expand All @@ -418,7 +423,7 @@ struct SimInstantiateOpLowering
ValueRange{allocated});
}

rewriter.create<LLVM::CallOp>(loc, freeFunc, ValueRange{allocated});
rewriter.create<LLVM::CallOp>(loc, freeFunc.value(), ValueRange{allocated});
rewriter.eraseOp(op);

return success();
Expand Down Expand Up @@ -550,6 +555,8 @@ struct SimEmitValueOpLowering
auto printfFunc = LLVM::lookupOrCreateFn(
moduleOp, "printf", LLVM::LLVMPointerType::get(getContext()),
LLVM::LLVMVoidType::get(getContext()), true);
if (failed(printfFunc))
return printfFunc;

// Insert the format string if not already available.
SmallString<16> formatStrName{"_arc_sim_emit_"};
Expand Down Expand Up @@ -580,7 +587,7 @@ struct SimEmitValueOpLowering
Value formatStrGlobalPtr =
rewriter.create<LLVM::AddressOfOp>(loc, formatStrGlobal);
rewriter.replaceOpWithNewOp<LLVM::CallOp>(
op, printfFunc, ValueRange{formatStrGlobalPtr, toPrint});
op, printfFunc.value(), ValueRange{formatStrGlobalPtr, toPrint});

return success();
}
Expand Down
8 changes: 5 additions & 3 deletions lib/Conversion/SMTToZ3LLVM/LowerSMTToZ3LLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,11 @@ class SMTLoweringPattern : public OpConversionPattern<OpTy> {
auto module =
builder.getBlock()->getParent()->getParentOfType<ModuleOp>();
builder.setInsertionPointToEnd(module.getBody());
funcOp = LLVM::lookupOrCreateFn(module, name, funcType.getParams(),
funcType.getReturnType(),
funcType.getVarArg());
auto funcOpResult = LLVM::lookupOrCreateFn(
module, name, funcType.getParams(), funcType.getReturnType(),
funcType.getVarArg());
assert(succeeded(funcOpResult) && "expected to lookup or create printf");
funcOp = funcOpResult.value();
}
return builder.create<LLVM::CallOp>(loc, funcOp, args);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Dialect/FSM/FSMOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void MachineOp::build(OpBuilder &builder, OperationState &state, StringRef name,
if (argAttrs.empty())
return;
assert(type.getNumInputs() == argAttrs.size());
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, state, argAttrs,
/*resultAttrs=*/std::nullopt, MachineOp::getArgAttrsAttrName(state.name),
MachineOp::getResAttrsAttrName(state.name));
Expand Down
4 changes: 2 additions & 2 deletions lib/Dialect/Handshake/HandshakeOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ parseFuncOpArgs(OpAsmParser &parser,
SmallVectorImpl<Type> &resTypes,
SmallVectorImpl<DictionaryAttr> &resAttrs) {
bool isVariadic;
if (mlir::function_interface_impl::parseFunctionSignature(
if (mlir::function_interface_impl::parseFunctionSignatureWithArguments(
parser, /*allowVariadic=*/true, entryArgs, isVariadic, resTypes,
resAttrs)
.failed())
Expand Down Expand Up @@ -641,7 +641,7 @@ ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
result.attributes) ||
parseFuncOpArgs(parser, args, resTypes, resAttributes))
return failure();
mlir::function_interface_impl::addArgAndResultAttrs(
mlir::call_interface_impl::addArgAndResultAttrs(
builder, result, args, resAttributes,
handshake::FuncOp::getArgAttrsAttrName(result.name),
handshake::FuncOp::getResAttrsAttrName(result.name));
Expand Down
8 changes: 4 additions & 4 deletions lib/Dialect/SystemC/SystemCOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ ParseResult SCModuleOp::parse(OpAsmParser &parser, OperationState &result) {
result.addAttribute(SCModuleOp::getFunctionTypeAttrName(result.name),
functionType);

mlir::function_interface_impl::addArgAndResultAttrs(
mlir::call_interface_impl::addArgAndResultAttrs(
parser.getBuilder(), result, entryArgs, resultAttrs,
SCModuleOp::getArgAttrsAttrName(result.name),
SCModuleOp::getResAttrsAttrName(result.name));
Expand Down Expand Up @@ -855,7 +855,7 @@ void FuncOp::build(OpBuilder &odsBuilder, OperationState &odsState,
if (argAttrs.empty())
return;
assert(type.getNumInputs() == argAttrs.size());
mlir::function_interface_impl::addArgAndResultAttrs(
mlir::call_interface_impl::addArgAndResultAttrs(
odsBuilder, odsState, argAttrs,
/*resultAttrs=*/std::nullopt, FuncOp::getArgAttrsAttrName(odsState.name),
FuncOp::getResAttrsAttrName(odsState.name));
Expand Down Expand Up @@ -893,7 +893,7 @@ ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
// Parse the function signature.
mlir::SMLoc signatureLocation = parser.getCurrentLocation();
bool isVariadic = false;
if (mlir::function_interface_impl::parseFunctionSignature(
if (mlir::function_interface_impl::parseFunctionSignatureWithArguments(
parser, false, entryArgs, isVariadic, resultTypes, resultAttrs))
return failure();

Expand Down Expand Up @@ -935,7 +935,7 @@ ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {

// Add the attributes to the function arguments.
assert(resultAttrs.size() == resultTypes.size());
mlir::function_interface_impl::addArgAndResultAttrs(
mlir::call_interface_impl::addArgAndResultAttrs(
builder, result, entryArgs, resultAttrs,
FuncOp::getArgAttrsAttrName(result.name),
FuncOp::getResAttrsAttrName(result.name));
Expand Down
7 changes: 6 additions & 1 deletion lib/Tools/circt-bmc/LowerToBMC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ void LowerToBMCPass::runOnOperation() {
// Lookup or declare printf function.
auto printfFunc =
LLVM::lookupOrCreateFn(moduleOp, "printf", ptrTy, voidTy, true);
if (failed(printfFunc)) {
moduleOp->emitError("failed to lookup or create printf");
return signalPassFailure();
}

// Replace the top-module with a function performing the BMC
auto entryFunc = builder.create<func::FuncOp>(
Expand Down Expand Up @@ -203,7 +207,8 @@ void LowerToBMCPass::runOnOperation() {

auto formatString = builder.create<LLVM::SelectOp>(
loc, bmcOp.getResult(), successStrAddr.value(), failureStrAddr.value());
builder.create<LLVM::CallOp>(loc, printfFunc, ValueRange{formatString});
builder.create<LLVM::CallOp>(loc, printfFunc.value(),
ValueRange{formatString});
builder.create<func::ReturnOp>(loc);

if (insertMainFunc) {
Expand Down
7 changes: 6 additions & 1 deletion lib/Tools/circt-lec/ConstructLEC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ void ConstructLECPass::runOnOperation() {
// Lookup or declare printf function.
auto printfFunc =
LLVM::lookupOrCreateFn(getOperation(), "printf", ptrTy, voidTy, true);
if (failed(printfFunc)) {
getOperation()->emitError("failed to lookup or create printf");
return signalPassFailure();
}

// Lookup the modules.
auto moduleA = lookupModule(firstModule);
Expand Down Expand Up @@ -144,7 +148,8 @@ void ConstructLECPass::runOnOperation() {
lookupOrCreateStringGlobal(builder, getOperation(), "c1 != c2\n");
Value formatString = builder.create<LLVM::SelectOp>(
loc, areEquivalent, eqFormatString, neqFormatString);
builder.create<LLVM::CallOp>(loc, printfFunc, ValueRange{formatString});
builder.create<LLVM::CallOp>(loc, printfFunc.value(),
ValueRange{formatString});

builder.create<func::ReturnOp>(loc, ValueRange{});
}
2 changes: 1 addition & 1 deletion llvm
Submodule llvm updated 6943 files
2 changes: 1 addition & 1 deletion test/Conversion/ArcToLLVM/lower-arc-to-llvm.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func.func @funcCallOp(%arg0: i32) -> (i32, i32) {
// CHECK-NEXT: [[V1:%.+]] = llvm.extractvalue [[V0]][0] : !llvm.struct<(i32, i32)>
// CHECK-NEXT: [[V2:%.+]] = llvm.extractvalue [[V0]][1] : !llvm.struct<(i32, i32)>
%0:2 = func.call @dummyFuncCallee(%arg0) : (i32) -> (i32, i32)
// CHECK-NEXT: [[V3:%.+]] = llvm.mlir.undef : !llvm.struct<(i32, i32)>
// CHECK-NEXT: [[V3:%.+]] = llvm.mlir.poison : !llvm.struct<(i32, i32)>
// CHECK-NEXT: [[V4:%.+]] = llvm.insertvalue [[V1]], [[V3]][0] : !llvm.struct<(i32, i32)>
// CHECK-NEXT: [[V5:%.+]] = llvm.insertvalue [[V2]], [[V4]][1] : !llvm.struct<(i32, i32)>
// CHECK-NEXT: llvm.return [[V5]] :
Expand Down

0 comments on commit f6559a2

Please sign in to comment.