/// Returns the builtin type equivalent to be used in attributes for the given
/// LLVM IR dialect type.
Type getStdTypeForAttr(Type type);
- /// Return `value` as an attribute to attach to a GlobalOp.
+ /// Returns `value` as an attribute to attach to a GlobalOp.
Attribute getConstantAsAttr(llvm::Constant *value);
- /// Return `constant` as an MLIR Value. This could either be a ConstantOp, or
- /// an expanded sequence of ops in the current function's entry block (for
+ /// Converts the LLVM constant to an MLIR value produced by a ConstantOp,
+ /// AddressOfOp, NullOp, or to an expanded sequence of operations (for
/// ConstantExprs or ConstantGEPs).
- Value processConstant(llvm::Constant *constant);
+ Value convertConstantInPlace(llvm::Constant *constant);
+ /// Converts the LLVM constant to an MLIR value using the
+ /// `convertConstantInPlace` method and inserts the constant at the start of
+ /// the function entry block.
+ Value convertConstant(llvm::Constant *constant);
+
+ /// Set the constant insertion point to the start of the given block.
+ void setConstantInsertionPointToStart(Block *block) {
+ constantInsertionBlock = block;
+ constantInsertionOp = nullptr;
+ }
- /// Builder pointing at where the next Instruction should be generated.
+ /// Builder pointing at where the next instruction should be generated.
OpBuilder builder;
+ /// Block to insert the next constant into.
+ Block *constantInsertionBlock = nullptr;
+ /// Operation to insert the next constant after.
+ Operation *constantInsertionOp = nullptr;
+ /// Operation to insert the next global after.
+ Operation *globalInsertionOp = nullptr;
/// The current context.
MLIRContext *context;
/// The current module being created.
ModuleOp module;
- /// The entry block of the current function being processed.
- Block *currentEntryBlock = nullptr;
-
- /// Globals are inserted before the first function, if any.
- Block::iterator getGlobalInsertPt() {
- Block::iterator it = module.getBody()->begin();
- Block::iterator endIt = module.getBody()->end();
- while (it != endIt && !isa<LLVMFuncOp>(it))
- ++it;
- return it;
- }
-
- /// Functions are always inserted before the module terminator.
- Block::iterator getFuncInsertPt() {
- return std::prev(module.getBody()->end());
- }
/// Function-local mapping between original and imported block.
DenseMap<llvm::BasicBlock *, Block *> blockMapping;
if (it != globals.end())
return it->second;
- OpBuilder b(module.getBody(), getGlobalInsertPt());
+ // Insert the global after the last one or at the start of the module.
+ OpBuilder::InsertionGuard guard(builder);
+ if (!globalInsertionOp) {
+ builder.setInsertionPointToStart(module.getBody());
+ } else {
+ builder.setInsertionPointAfter(globalInsertionOp);
+ }
+
Attribute valueAttr;
if (gv->hasInitializer())
valueAttr = getConstantAsAttr(gv->getInitializer());
alignment = align.value();
}
- GlobalOp op = b.create<GlobalOp>(
+ GlobalOp op = builder.create<GlobalOp>(
UnknownLoc::get(context), type, gv->isConstant(),
convertLinkageFromLLVM(gv->getLinkage()), gv->getName(), valueAttr,
alignment, /*addr_space=*/gv->getAddressSpace(),
/*dso_local=*/gv->isDSOLocal(), /*thread_local=*/gv->isThreadLocal());
+ globalInsertionOp = op;
if (gv->hasInitializer() && !valueAttr) {
- Region &r = op.getInitializerRegion();
- currentEntryBlock = b.createBlock(&r);
- b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
- Value v = processConstant(gv->getInitializer());
- if (!v)
- return nullptr;
- b.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({v}));
+ Block *block = builder.createBlock(&op.getInitializerRegion());
+ setConstantInsertionPointToStart(block);
+ Value value = convertConstant(gv->getInitializer());
+ builder.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({value}));
}
if (gv->hasAtLeastLocalUnnamedAddr())
op.setUnnamedAddr(convertUnnamedAddrFromLLVM(gv->getUnnamedAddr()));
return globals[gv] = op;
}
-Value Importer::processConstant(llvm::Constant *constant) {
- OpBuilder bEntry(currentEntryBlock, currentEntryBlock->begin());
+Value Importer::convertConstantInPlace(llvm::Constant *constant) {
if (Attribute attr = getConstantAsAttr(constant)) {
// These constants can be represented as attributes.
- OpBuilder b(currentEntryBlock, currentEntryBlock->begin());
Type type = convertType(constant->getType());
if (auto symbolRef = attr.dyn_cast<FlatSymbolRefAttr>())
- return bEntry.create<AddressOfOp>(UnknownLoc::get(context), type,
- symbolRef.getValue());
- return bEntry.create<ConstantOp>(UnknownLoc::get(context), type, attr);
+ return builder.create<AddressOfOp>(UnknownLoc::get(context), type,
+ symbolRef.getValue());
+ return builder.create<ConstantOp>(UnknownLoc::get(context), type, attr);
}
if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(constant)) {
Type type = convertType(cn->getType());
- return bEntry.create<NullOp>(UnknownLoc::get(context), type);
+ return builder.create<NullOp>(UnknownLoc::get(context), type);
}
if (auto *gv = dyn_cast<llvm::GlobalVariable>(constant))
- return bEntry.create<AddressOfOp>(UnknownLoc::get(context),
- processGlobal(gv));
+ return builder.create<AddressOfOp>(UnknownLoc::get(context),
+ processGlobal(gv));
if (auto *ce = dyn_cast<llvm::ConstantExpr>(constant)) {
llvm::Instruction *i = ce->getAsInstruction();
- OpBuilder::InsertionGuard guard(builder);
- builder.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
if (failed(processInstruction(i)))
return nullptr;
assert(valueMapping.count(i));
}
if (auto *ue = dyn_cast<llvm::UndefValue>(constant)) {
Type type = convertType(ue->getType());
- return bEntry.create<UndefOp>(UnknownLoc::get(context), type);
+ return builder.create<UndefOp>(UnknownLoc::get(context), type);
}
if (isa<llvm::ConstantAggregate>(constant) ||
bool useInsertValue = rootType.isa<LLVMArrayType, LLVMStructType>();
assert((useInsertValue || LLVM::isCompatibleVectorType(rootType)) &&
"unrecognized aggregate type");
- Value root = bEntry.create<UndefOp>(UnknownLoc::get(context), rootType);
+ Value root = builder.create<UndefOp>(UnknownLoc::get(context), rootType);
for (unsigned i = 0; i < numElements; ++i) {
llvm::Constant *element = getElement(i);
- Value elementValue = processConstant(element);
+ Value elementValue = convertConstantInPlace(element);
if (!elementValue)
return nullptr;
if (useInsertValue) {
- root = bEntry.create<InsertValueOp>(UnknownLoc::get(context), root,
- elementValue, i);
+ root = builder.create<InsertValueOp>(UnknownLoc::get(context), root,
+ elementValue, i);
} else {
- Attribute indexAttr = bEntry.getI32IntegerAttr(static_cast<int32_t>(i));
- Value indexValue = bEntry.create<ConstantOp>(
- UnknownLoc::get(context), bEntry.getI32Type(), indexAttr);
+ Attribute indexAttr =
+ builder.getI32IntegerAttr(static_cast<int32_t>(i));
+ Value indexValue = builder.create<ConstantOp>(
+ UnknownLoc::get(context), builder.getI32Type(), indexAttr);
if (!indexValue)
return nullptr;
- root = bEntry.create<InsertElementOp>(
+ root = builder.create<InsertElementOp>(
UnknownLoc::get(context), rootType, root, elementValue, indexValue);
}
}
return root;
}
- emitError(UnknownLoc::get(context))
- << "unhandled constant: " << diag(*constant);
return nullptr;
}
+Value Importer::convertConstant(llvm::Constant *constant) {
+ assert(constantInsertionBlock &&
+ "expected the constant insertion block to be non-null");
+
+ // Insert the constant after the last one or at the start or the entry block.
+ OpBuilder::InsertionGuard guard(builder);
+ if (!constantInsertionOp) {
+ builder.setInsertionPointToStart(constantInsertionBlock);
+ } else {
+ builder.setInsertionPointAfter(constantInsertionOp);
+ }
+
+ // Convert the constant in-place and update the insertion point if successful.
+ if (Value result = convertConstantInPlace(constant)) {
+ constantInsertionOp = result.getDefiningOp();
+ return result;
+ }
+
+ llvm::errs() << diag(*constant) << "\n";
+ llvm_unreachable("unhandled constant");
+}
+
Value Importer::processValue(llvm::Value *value) {
auto it = valueMapping.find(value);
if (it != valueMapping.end())
return it->second;
- // Process constants such as immediate arguments that have no mapping.
+ // Convert constants such as immediate arguments that have no mapping.
if (auto *c = dyn_cast<llvm::Constant>(value))
- return processConstant(c);
+ return convertConstant(c);
llvm::errs() << diag(*value) << "\n";
llvm_unreachable("unhandled value");
SmallVector<Value, 4> ops;
for (unsigned i = 0, ie = lpi->getNumClauses(); i < ie; i++)
- ops.push_back(processConstant(lpi->getClause(i)));
+ ops.push_back(convertConstant(lpi->getClause(i)));
Type ty = convertType(lpi->getType());
Value res = builder.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
bool dsoLocal = func->hasLocalLinkage();
CConv cconv = convertCConvFromLLVM(func->getCallingConv());
- builder.setInsertionPoint(module.getBody(), getFuncInsertPt());
+ // Insert the function at the end of the module.
+ OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPoint(module.getBody(), module.getBody()->end());
+
LLVMFuncOp funcOp = builder.create<LLVMFuncOp>(
UnknownLoc::get(context), func->getName(), functionType,
convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
builder.createBlock(&funcOp.getBody(), funcOp.getBody().end());
mapBlock(&bb, block);
}
- currentEntryBlock = &funcOp.getFunctionBody().getBlocks().front();
// Add function arguments to the entry block.
for (const auto &it : llvm::enumerate(func->args())) {
// operands defined in a dominating block have a valid mapping to an MLIR
// value once a block is translated.
SetVector<llvm::BasicBlock *> blocks = getTopologicallySortedBlocks(func);
+ setConstantInsertionPointToStart(lookupBlock(blocks.front()));
for (llvm::BasicBlock *bb : blocks) {
if (failed(processBasicBlock(bb, lookupBlock(bb))))
return failure();
@g4 = external global i32, align 8
; CHECK: llvm.mlir.global internal constant @int_gep() {addr_space = 0 : i32, dso_local} : !llvm.ptr<i32> {
-; CHECK-DAG: %[[addr:[0-9]+]] = llvm.mlir.addressof @g4 : !llvm.ptr<i32>
-; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
+; CHECK: %[[addr:[0-9]+]] = llvm.mlir.addressof @g4 : !llvm.ptr<i32>
+; CHECK: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
; CHECK-NEXT: %[[gepinit:[0-9]+]] = llvm.getelementptr %[[addr]][%[[c2]]] : (!llvm.ptr<i32>, i32) -> !llvm.ptr<i32>
; CHECK-NEXT: llvm.return %[[gepinit]] : !llvm.ptr<i32>
; CHECK-NEXT: }
; FIXME: function attributes.
; CHECK-LABEL: llvm.func internal @f1(%arg0: i64) -> i32 attributes {dso_local} {
; CHECK-DBG: llvm.func internal @f1(%arg0: i64 loc(unknown)) -> i32 attributes {dso_local} {
-; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
-; CHECK-DAG: %[[c42:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
-; CHECK-DAG: %[[c1:[0-9]+]] = llvm.mlir.constant(true) : i1
-; CHECK-DAG: %[[c43:[0-9]+]] = llvm.mlir.constant(43 : i32) : i32
+; CHECK: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
+; CHECK: %[[c1:[0-9]+]] = llvm.mlir.constant(true) : i1
+; CHECK: %[[c43:[0-9]+]] = llvm.mlir.constant(43 : i32) : i32
+; CHECK: %[[c42:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
define internal dso_local i32 @f1(i64 %a) norecurse {
entry:
; CHECK: %{{[0-9]+}} = llvm.inttoptr %arg0 : i64 to !llvm.ptr<i64>
; %{{[0-9]+}} = llvm.ptrtoint %[[addrof2]] : !llvm.ptr<f64> to i64
; %{{[0-9]+}} = llvm.getelementptr %[[addrof]][%3] : (!llvm.ptr<f64>, i32) -> !llvm.ptr<f64>
%bb = ptrtoint double* @g2 to i64
- %cc = getelementptr double, double* @g2, i32 2
+ %cc = getelementptr double, double* @g2, i32 3
; CHECK: %[[b:[0-9]+]] = llvm.trunc %arg0 : i64 to i32
; CHECK-DBG: llvm.trunc %arg0 : i64 to i32 loc(#[[UNKNOWNLOC]])
%b = trunc i64 %a to i32
; Testing rest of the floating point constant kinds.
; CHECK-LABEL: llvm.func @FPConstant(%arg0: f16, %arg1: bf16, %arg2: f128, %arg3: f80)
define void @FPConstant(half %a, bfloat %b, fp128 %c, x86_fp80 %d) {
- ; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(7.000000e+00 : f80) : f80
- ; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(0.000000e+00 : f128) : f128
- ; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(1.000000e+00 : bf16) : bf16
- ; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(1.000000e+00 : f16) : f16
+ ; CHECK: %[[C0:.+]] = llvm.mlir.constant(1.000000e+00 : f16) : f16
+ ; CHECK: %[[C1:.+]] = llvm.mlir.constant(1.000000e+00 : bf16) : bf16
+ ; CHECK: %[[C2:.+]] = llvm.mlir.constant(0.000000e+00 : f128) : f128
+ ; CHECK: %[[C3:.+]] = llvm.mlir.constant(7.000000e+00 : f80) : f80
- ; CHECK: llvm.fadd %[[C3]], %arg0 : f16
+ ; CHECK: llvm.fadd %[[C0]], %arg0 : f16
%1 = fadd half 1.0, %a
- ; CHECK: llvm.fadd %[[C2]], %arg1 : bf16
+ ; CHECK: llvm.fadd %[[C1]], %arg1 : bf16
%2 = fadd bfloat 1.0, %b
- ; CHECK: llvm.fadd %[[C1]], %arg2 : f128
+ ; CHECK: llvm.fadd %[[C2]], %arg2 : f128
%3 = fadd fp128 0xL00000000000000000000000000000000, %c
- ; CHECK: llvm.fadd %[[C0]], %arg3 : f80
+ ; CHECK: llvm.fadd %[[C3]], %arg3 : f80
%4 = fadd x86_fp80 0xK4001E000000000000000, %d
ret void
}
; RUN: mlir-translate --import-llvm %s | FileCheck %s
-
-; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(7 : i32) : i32
-; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(8 : i16) : i16
-; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(4 : i8) : i8
-; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(9 : i32) : i32
; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"SimpleAggType", (i32, i8, i16, i32)>
-; CHECK: %[[CHAIN0:.+]] = llvm.insertvalue %[[C3]], %[[ROOT]][0]
-; CHECK: %[[CHAIN1:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN0]][1]
-; CHECK: %[[CHAIN2:.+]] = llvm.insertvalue %[[C1]], %[[CHAIN1]][2]
-; CHECK: %[[CHAIN3:.+]] = llvm.insertvalue %[[C0]], %[[CHAIN2]][3]
+; CHECK: %[[C0:.+]] = llvm.mlir.constant(9 : i32) : i32
+; CHECK: %[[CHAIN0:.+]] = llvm.insertvalue %[[C0]], %[[ROOT]][0]
+; CHECK: %[[C1:.+]] = llvm.mlir.constant(4 : i8) : i8
+; CHECK: %[[CHAIN1:.+]] = llvm.insertvalue %[[C1]], %[[CHAIN0]][1]
+; CHECK: %[[C2:.+]] = llvm.mlir.constant(8 : i16) : i16
+; CHECK: %[[CHAIN2:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN1]][2]
+; CHECK: %[[C3:.+]] = llvm.mlir.constant(7 : i32) : i32
+; CHECK: %[[CHAIN3:.+]] = llvm.insertvalue %[[C3]], %[[CHAIN2]][3]
; CHECK: llvm.return %[[CHAIN3]]
%SimpleAggType = type {i32, i8, i16, i32}
@simpleAgg = global %SimpleAggType {i32 9, i8 4, i16 8, i32 7}
-; CHECK: %[[NP:.+]] = llvm.mlir.null : !llvm.ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>
-; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(4 : i32) : i32
-; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(3 : i16) : i16
-; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(2 : i8) : i8
-; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(1 : i32) : i32
-; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"SimpleAggType", (i32, i8, i16, i32)>
-; CHECK: %[[CHAIN0:.+]] = llvm.insertvalue %[[C3]], %[[ROOT]][0]
+; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"NestedAggType", (struct<"SimpleAggType", (i32, i8, i16, i32)>, ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>)>
+; CHECK: %[[NESTED:.+]] = llvm.mlir.undef : !llvm.struct<"SimpleAggType", (i32, i8, i16, i32)>
+; CHECK: %[[C1:.+]] = llvm.mlir.constant(1 : i32) : i32
+; CHECK: %[[CHAIN0:.+]] = llvm.insertvalue %[[C1]], %[[NESTED]][0]
+; CHECK: %[[C2:.+]] = llvm.mlir.constant(2 : i8) : i8
; CHECK: %[[CHAIN1:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN0]][1]
-; CHECK: %[[CHAIN2:.+]] = llvm.insertvalue %[[C1]], %[[CHAIN1]][2]
-; CHECK: %[[CHAIN3:.+]] = llvm.insertvalue %[[C0]], %[[CHAIN2]][3]
-; CHECK: %[[ROOT2:.+]] = llvm.mlir.undef : !llvm.struct<"NestedAggType", (struct<"SimpleAggType", (i32, i8, i16, i32)>, ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>)>
-; CHECK: %[[CHAIN4:.+]] = llvm.insertvalue %[[CHAIN3]], %[[ROOT2]][0]
+; CHECK: %[[C3:.+]] = llvm.mlir.constant(3 : i16) : i16
+; CHECK: %[[CHAIN2:.+]] = llvm.insertvalue %[[C3]], %[[CHAIN1]][2]
+; CHECK: %[[C4:.+]] = llvm.mlir.constant(4 : i32) : i32
+; CHECK: %[[CHAIN3:.+]] = llvm.insertvalue %[[C4]], %[[CHAIN2]][3]
+; CHECK: %[[CHAIN4:.+]] = llvm.insertvalue %[[CHAIN3]], %[[ROOT]][0]
+; CHECK: %[[NP:.+]] = llvm.mlir.null : !llvm.ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>
; CHECK: %[[CHAIN5:.+]] = llvm.insertvalue %[[NP]], %[[CHAIN4]][1]
; CHECK: llvm.return %[[CHAIN5]]
%NestedAggType = type {%SimpleAggType, %SimpleAggType*}
@nestedAgg = global %NestedAggType { %SimpleAggType{i32 1, i8 2, i16 3, i32 4}, %SimpleAggType* null }
-; CHECK: %[[C0:.+]] = llvm.mlir.null : !llvm.ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>
-; CHECK: %[[C1:.+]] = llvm.mlir.null : !llvm.ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>
; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.vec<2 x ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>>
+; CHECK: %[[C0:.+]] = llvm.mlir.null : !llvm.ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>
; CHECK: %[[P0:.+]] = llvm.mlir.constant(0 : i32) : i32
-; CHECK: %[[CHAIN0:.+]] = llvm.insertelement %[[C1]], %[[ROOT]][%[[P0]] : i32] : !llvm.vec<2 x ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>>
+; CHECK: %[[CHAIN0:.+]] = llvm.insertelement %[[C0]], %[[ROOT]][%[[P0]] : i32] : !llvm.vec<2 x ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>>
+; CHECK: %[[C1:.+]] = llvm.mlir.null : !llvm.ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>
; CHECK: %[[P1:.+]] = llvm.mlir.constant(1 : i32) : i32
-; CHECK: %[[CHAIN1:.+]] = llvm.insertelement %[[C0]], %[[CHAIN0]][%[[P1]] : i32] : !llvm.vec<2 x ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>>
+; CHECK: %[[CHAIN1:.+]] = llvm.insertelement %[[C1]], %[[CHAIN0]][%[[P1]] : i32] : !llvm.vec<2 x ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>>
; CHECK: llvm.return %[[CHAIN1]] : !llvm.vec<2 x ptr<struct<"SimpleAggType", (i32, i8, i16, i32)>>>
@vectorAgg = global <2 x %SimpleAggType*> <%SimpleAggType* null, %SimpleAggType* null>
; only wrote minimum level of checks.
%my_struct = type {i32, i8*}
+; CHECK: llvm.mlir.addressof @str0 : !llvm.ptr<array<5 x i8>>
; CHECK: llvm.mlir.addressof @str1 : !llvm.ptr<array<5 x i8>>
-; CHECK: llvm.getelementptr
-; CHECK: llvm.mlir.constant(7 : i32) : i32
+; CHECK: llvm.mlir.undef : !llvm.array<2 x struct<"my_struct", (i32, ptr<i8>)>>
; CHECK: llvm.mlir.undef : !llvm.struct<"my_struct", (i32, ptr<i8>)>
+; CHECK: llvm.mlir.constant(8 : i32) : i32
; CHECK: llvm.insertvalue
-; CHECK: llvm.insertvalue
-; CHECK: llvm.mlir.addressof @str0 : !llvm.ptr<array<5 x i8>>
; CHECK: llvm.getelementptr
-; CHECK: llvm.mlir.constant(8 : i32) : i32
-; CHECK: llvm.mlir.undef : !llvm.struct<"my_struct", (i32, ptr<i8>)>
; CHECK: llvm.insertvalue
; CHECK: llvm.insertvalue
-; CHECK: llvm.mlir.undef : !llvm.array<2 x struct<"my_struct", (i32, ptr<i8>)>>
+; CHECK: llvm.mlir.undef : !llvm.struct<"my_struct", (i32, ptr<i8>)>
+; CHECK: llvm.mlir.constant(7 : i32) : i32
+; CHECK: llvm.insertvalue
+; CHECK: llvm.getelementptr
; CHECK: llvm.insertvalue
; CHECK: llvm.insertvalue
; CHECK: llvm.return
@str0 = private unnamed_addr constant [5 x i8] c"aaaa\00"
@str1 = private unnamed_addr constant [5 x i8] c"bbbb\00"
@g = global [2 x %my_struct] [%my_struct {i32 8, i8* getelementptr ([5 x i8], [5 x i8]* @str0, i32 0, i32 0)}, %my_struct {i32 7, i8* getelementptr ([5 x i8], [5 x i8]* @str1, i32 0, i32 0)}]
-
; Thus, we only wrote minimum level of checks.
%my_struct = type {i32, i8*}
-; CHECK: llvm.mlir.constant(3 : i32) : i32
-; CHECK: llvm.mlir.constant(2 : i32) : i32
+; CHECK: llvm.mlir.addressof @str0 : !llvm.ptr<array<5 x i8>>
+; CHECK: llvm.mlir.constant(0 : i32) : i32
+; CHECK: llvm.mlir.constant(1 : i32) : i32
; CHECK: llvm.mlir.addressof @str1 : !llvm.ptr<array<5 x i8>>
-; CHECK: llvm.getelementptr
-; CHECK: llvm.mlir.constant(7 : i32) : i32
+; CHECK: llvm.mlir.constant(2 : i32) : i32
+; CHECK: llvm.mlir.constant(3 : i32) : i32
+; CHECK: llvm.mlir.undef : !llvm.array<2 x struct<"my_struct", (i32, ptr<i8>)>>
; CHECK: llvm.mlir.undef : !llvm.struct<"my_struct", (i32, ptr<i8>)>
+; CHECK: llvm.mlir.constant(8 : i32) : i32
; CHECK: llvm.insertvalue
-; CHECK: llvm.insertvalue
-; CHECK: llvm.mlir.constant(1 : i32) : i32
-; CHECK: llvm.mlir.constant(0 : i32) : i32
-; CHECK: llvm.mlir.addressof @str0 : !llvm.ptr<array<5 x i8>>
; CHECK: llvm.getelementptr
-; CHECK: llvm.mlir.constant(8 : i32) : i32
-; CHECK: llvm.mlir.undef : !llvm.struct<"my_struct", (i32, ptr<i8>)>
; CHECK: llvm.insertvalue
; CHECK: llvm.insertvalue
-; CHECK: llvm.mlir.undef : !llvm.array<2 x struct<"my_struct", (i32, ptr<i8>)>>
+; CHECK: llvm.mlir.undef : !llvm.struct<"my_struct", (i32, ptr<i8>)>
+; CHECK: llvm.mlir.constant(7 : i32) : i32
+; CHECK: llvm.insertvalue
+; CHECK: llvm.getelementptr
; CHECK: llvm.insertvalue
; CHECK: llvm.insertvalue
; CHECK: llvm.return
@str0 = private unnamed_addr constant [5 x i8] c"aaaa\00"
@str1 = private unnamed_addr constant [5 x i8] c"bbbb\00"
@g = global [2 x %my_struct] [%my_struct {i32 8, i8* getelementptr ([5 x i8], [5 x i8]* @str0, i32 0, i32 1)}, %my_struct {i32 7, i8* getelementptr ([5 x i8], [5 x i8]* @str1, i32 2, i32 3)}]
-
; CHECK-SAME: %[[ARG3:[a-zA-Z0-9]+]]
; CHECK-SAME: %[[ARG4:[a-zA-Z0-9]+]]
define void @integer_arith(i32 %arg1, i32 %arg2, i64 %arg3, i64 %arg4) {
- ; CHECK-DAG: %[[C1:[0-9]+]] = llvm.mlir.constant(-7 : i32) : i32
- ; CHECK-DAG: %[[C2:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
+ ; CHECK: %[[C1:[0-9]+]] = llvm.mlir.constant(-7 : i32) : i32
+ ; CHECK: %[[C2:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
; CHECK: llvm.add %[[ARG1]], %[[C1]] : i32
%1 = add i32 %arg1, -7
; CHECK: llvm.add %[[C2]], %[[ARG2]] : i32
; CHECK-SAME: %[[ARG3:[a-zA-Z0-9]+]]
; CHECK-SAME: %[[ARG4:[a-zA-Z0-9]+]]
define void @fp_arith(float %arg1, float %arg2, double %arg3, double %arg4) {
- ; CHECK: %[[C1:[0-9]+]] = llvm.mlir.constant(3.030000e+01 : f64) : f64
- ; CHECK: %[[C2:[0-9]+]] = llvm.mlir.constant(3.030000e+01 : f32) : f32
- ; CHECK: llvm.fadd %[[C2]], %[[ARG1]] : f32
+ ; CHECK: %[[C1:[0-9]+]] = llvm.mlir.constant(3.030000e+01 : f32) : f32
+ ; CHECK: %[[C2:[0-9]+]] = llvm.mlir.constant(3.030000e+01 : f64) : f64
+ ; CHECK: llvm.fadd %[[C1]], %[[ARG1]] : f32
%1 = fadd float 0x403E4CCCC0000000, %arg1
; CHECK: llvm.fadd %[[ARG1]], %[[ARG2]] : f32
%2 = fadd float %arg1, %arg2
- ; CHECK: llvm.fadd %[[C1]], %[[ARG3]] : f64
+ ; CHECK: llvm.fadd %[[C2]], %[[ARG3]] : f64
%3 = fadd double 3.030000e+01, %arg3
; CHECK: llvm.fsub %[[ARG1]], %[[ARG2]] : f32
%4 = fsub float %arg1, %arg2
; CHECK-SAME: %[[ARG3:[a-zA-Z0-9]+]]
; CHECK-SAME: %[[ARG4:[a-zA-Z0-9]+]]
define void @integer_arith(i32 %arg1, i32 %arg2, i64 %arg3, i64 %arg4) {
- ; CHECK-DAG: %[[C1:[0-9]+]] = llvm.mlir.constant(-7 : i32) : i32
- ; CHECK-DAG: %[[C2:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
+ ; CHECK: %[[C1:[0-9]+]] = llvm.mlir.constant(-7 : i32) : i32
+ ; CHECK: %[[C2:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
; CHECK: llvm.add %[[ARG1]], %[[C1]] : i32
; CHECK: llvm.add %[[C2]], %[[ARG2]] : i32
; CHECK: llvm.sub %[[ARG3]], %[[ARG4]] : i64
; RUN: mlir-translate -import-llvm %s | FileCheck %s
-define void @intrinsics() {
- ret void
-}
-
; CHECK-LABEL: llvm.func @fmuladd_test
define void @fmuladd_test(float %0, float %1, <8 x float> %2, i8* %3) {
; CHECK: llvm.intr.fmuladd(%{{.*}}, %{{.*}}, %{{.*}}) : (f32, f32, f32) -> f32
}
; CHECK-LABEL: llvm.func @ctlz_test
define void @ctlz_test(i32 %0, <8 x i32> %1) {
- ; CHECK-DAG: %[[falseval1:.+]] = llvm.mlir.constant(false) : i1
- ; CHECK-DAG: %[[falseval2:.+]] = llvm.mlir.constant(false) : i1
- ; CHECK: "llvm.intr.ctlz"(%{{.*}}, %[[falseval2]]) : (i32, i1) -> i32
+ ; CHECK: %[[falseval1:.+]] = llvm.mlir.constant(false) : i1
+ ; CHECK: %[[falseval2:.+]] = llvm.mlir.constant(false) : i1
+ ; CHECK: "llvm.intr.ctlz"(%{{.*}}, %[[falseval1]]) : (i32, i1) -> i32
%3 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- ; CHECK: "llvm.intr.ctlz"(%{{.*}}, %[[falseval1]]) : (vector<8xi32>, i1) -> vector<8xi32>
+ ; CHECK: "llvm.intr.ctlz"(%{{.*}}, %[[falseval2]]) : (vector<8xi32>, i1) -> vector<8xi32>
%4 = call <8 x i32> @llvm.ctlz.v8i32(<8 x i32> %1, i1 false)
ret void
}
; CHECK-LABEL: llvm.func @cttz_test
define void @cttz_test(i32 %0, <8 x i32> %1) {
- ; CHECK-DAG: %[[falseval1:.+]] = llvm.mlir.constant(false) : i1
- ; CHECK-DAG: %[[falseval2:.+]] = llvm.mlir.constant(false) : i1
- ; CHECK: "llvm.intr.cttz"(%{{.*}}, %[[falseval2]]) : (i32, i1) -> i32
+ ; CHECK: %[[falseval1:.+]] = llvm.mlir.constant(false) : i1
+ ; CHECK: %[[falseval2:.+]] = llvm.mlir.constant(false) : i1
+ ; CHECK: "llvm.intr.cttz"(%{{.*}}, %[[falseval1]]) : (i32, i1) -> i32
%3 = call i32 @llvm.cttz.i32(i32 %0, i1 false)
- ; CHECK: "llvm.intr.cttz"(%{{.*}}, %[[falseval1]]) : (vector<8xi32>, i1) -> vector<8xi32>
+ ; CHECK: "llvm.intr.cttz"(%{{.*}}, %[[falseval2]]) : (vector<8xi32>, i1) -> vector<8xi32>
%4 = call <8 x i32> @llvm.cttz.v8i32(<8 x i32> %1, i1 false)
ret void
}
; CHECK: %[[falseval1:.+]] = llvm.mlir.constant(false) : i1
; CHECK: %[[constant:.+]] = llvm.mlir.constant(10 : i64) : i64
; CHECK: %[[falseval2:.+]] = llvm.mlir.constant(false) : i1
- ; CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}, %[[falseval2]]) : (!llvm.ptr<i8>, !llvm.ptr<i8>, i32, i1) -> ()
+ ; CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}, %[[falseval1]]) : (!llvm.ptr<i8>, !llvm.ptr<i8>, i32, i1) -> ()
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* %2, i32 %0, i1 false)
- ; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}, %[[constant]], %[[falseval1]]) : (!llvm.ptr<i8>, !llvm.ptr<i8>, i64, i1) -> ()
+ ; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}, %[[constant]], %[[falseval2]]) : (!llvm.ptr<i8>, !llvm.ptr<i8>, i64, i1) -> ()
call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* %1, i8* %2, i64 10, i1 false)
ret void
}
; CHECK: llvm.mlir.global external @D()
; CHECK-SAME: !llvm.struct<"Domain", (ptr<ptr<struct<"Domain">>>, ptr<struct<"Domain">>)>
-; CHECK-DAG: %[[E0:.+]] = llvm.mlir.null : !llvm.ptr<struct<"Domain", (ptr<ptr<struct<"Domain">>>, ptr<struct<"Domain">>)>>
-; CHECK-DAG: %[[E1:.+]] = llvm.mlir.null : !llvm.ptr<ptr<struct<"Domain", (ptr<ptr<struct<"Domain">>>, ptr<struct<"Domain">>)>>>
; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"Domain", (ptr<ptr<struct<"Domain">>>, ptr<struct<"Domain">>)>
-; CHECK: %[[CHAIN:.+]] = llvm.insertvalue %[[E1]], %[[ROOT]][0]
-; CHECK: %[[RES:.+]] = llvm.insertvalue %[[E0]], %[[CHAIN]][1]
+; CHECK: %[[E0:.+]] = llvm.mlir.null : !llvm.ptr<ptr<struct<"Domain", (ptr<ptr<struct<"Domain">>>, ptr<struct<"Domain">>)>>>
+; CHECK: %[[CHAIN:.+]] = llvm.insertvalue %[[E0]], %[[ROOT]][0]
+; CHECK: %[[E1:.+]] = llvm.mlir.null : !llvm.ptr<struct<"Domain", (ptr<ptr<struct<"Domain">>>, ptr<struct<"Domain">>)>>
+; CHECK: %[[RES:.+]] = llvm.insertvalue %[[E1]], %[[CHAIN]][1]
; CHECK: llvm.return %[[RES]]
@D = global %Domain zeroinitializer