diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -173,7 +173,8 @@ def LLVM_AllocaOp : LLVM_Op<"alloca">, LLVM_MemOpPatterns { let arguments = (ins AnyInteger:$arraySize, OptionalAttr:$alignment, - OptionalAttr:$elem_type); + OptionalAttr:$elem_type, + UnitAttr:$inalloca); let results = (outs Res]>:$res); string llvmInstName = "Alloca"; @@ -184,16 +185,18 @@ : op.getType().cast().getElementType()); auto *inst = builder.CreateAlloca(elementType, addrSpace, $arraySize); }] # setAlignmentCode # [{ + inst->setUsedWithInAlloca($inalloca); $res = inst; }]; - // FIXME: Import attributes. string mlirBuilder = [{ auto *allocaInst = cast(inst); Type allocatedType = moduleImport.convertType(allocaInst->getAllocatedType()); unsigned alignment = allocaInst->getAlign().value(); $res = $_builder.create( - $_location, $_resultType, allocatedType, $arraySize, alignment); + $_location, $_resultType, $arraySize, + alignment == 0 ? IntegerAttr() : $_builder.getI64IntegerAttr(alignment), + TypeAttr::get(allocatedType), allocaInst->isUsedWithInAlloca()); }]; let builders = [ OpBuilder<(ins "Type":$resultType, "Value":$arraySize, @@ -203,9 +206,9 @@ "pass the allocated type explicitly if opaque pointers are used"); if (alignment == 0) return build($_builder, $_state, resultType, arraySize, IntegerAttr(), - TypeAttr()); + TypeAttr(), false); build($_builder, $_state, resultType, arraySize, - $_builder.getI64IntegerAttr(alignment), TypeAttr()); + $_builder.getI64IntegerAttr(alignment), TypeAttr(), false); }]>, OpBuilder<(ins "Type":$resultType, "Type":$elementType, "Value":$arraySize, CArg<"unsigned", "0">:$alignment), @@ -216,7 +219,7 @@ build($_builder, $_state, resultType, arraySize, alignment == 0 ? IntegerAttr() : $_builder.getI64IntegerAttr(alignment), - elemTypeAttr); + elemTypeAttr, false); }]> ]; diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -185,21 +185,30 @@ auto funcTy = FunctionType::get(getContext(), {getArraySize().getType()}, {getType()}); + if (getInalloca()) + p << " inalloca"; + p << ' ' << getArraySize() << " x " << elemTy; if (getAlignment() && *getAlignment() != 0) - p.printOptionalAttrDict((*this)->getAttrs(), {kElemTypeAttrName}); + p.printOptionalAttrDict((*this)->getAttrs(), + {kElemTypeAttrName, this->getInallocaAttrName()}); else p.printOptionalAttrDict((*this)->getAttrs(), - {"alignment", kElemTypeAttrName}); + {this->getAlignmentAttrName(), kElemTypeAttrName, + this->getInallocaAttrName()}); p << " : " << funcTy; } -// ::= `llvm.alloca` ssa-use `x` type attribute-dict? -// `:` type `,` type +// ::= `llvm.alloca` `inalloca`? ssa-use `x` type +// attribute-dict? `:` type `,` type ParseResult AllocaOp::parse(OpAsmParser &parser, OperationState &result) { OpAsmParser::UnresolvedOperand arraySize; Type type, elemType; SMLoc trailingTypeLoc; + + if (succeeded(parser.parseOptionalKeyword("inalloca"))) + result.addAttribute("inalloca", UnitAttr::get(parser.getContext())); + if (parser.parseOperand(arraySize) || parser.parseKeyword("x") || parser.parseType(elemType) || parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() || diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir --- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir @@ -327,6 +327,10 @@ llvm.alloca %size x i32 {alignment = 0} : (i64) -> (!llvm.ptr) // CHECK: llvm.alloca %{{.*}} x i32 {alignment = 8 : i64} : (i64) -> !llvm.ptr llvm.alloca %size x i32 {alignment = 8} : (i64) -> (!llvm.ptr) + // CHECK: llvm.alloca inalloca %{{.*}} x i32 : (i64) -> !llvm.ptr + llvm.alloca inalloca %size x i32 : (i64) -> !llvm.ptr + // CHECK: llvm.alloca inalloca %{{.*}} x i32 {alignment = 8 : i64} : (i64) -> !llvm.ptr + llvm.alloca inalloca %size x i32 {alignment = 8} : (i64) -> !llvm.ptr llvm.return } diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll --- a/mlir/test/Target/LLVMIR/Import/instructions.ll +++ b/mlir/test/Target/LLVMIR/Import/instructions.ll @@ -341,9 +341,13 @@ ; CHECK: llvm.alloca %[[C1]] x f64 {alignment = 8 : i64} : (i32) -> !llvm.ptr ; CHECK: llvm.alloca %[[SIZE]] x i32 {alignment = 8 : i64} : (i64) -> !llvm.ptr ; CHECK: llvm.alloca %[[SIZE]] x i32 {alignment = 4 : i64} : (i64) -> !llvm.ptr<3> + ; CHECK: llvm.alloca inalloca %[[SIZE]] x i32 {alignment = 4 : i64} : (i64) -> !llvm.ptr + ; CHECK: llvm.alloca inalloca %[[SIZE]] x i32 {alignment = 8 : i64} : (i64) -> !llvm.ptr %1 = alloca double %2 = alloca i32, i64 %size, align 8 %3 = alloca i32, i64 %size, addrspace(3) + %4 = alloca inalloca i32, i64 %size + %5 = alloca inalloca i32, i64 %size, align 8 ret ptr %1 } diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -1353,6 +1353,10 @@ llvm.alloca %size x i32 {alignment = 8} : (i64) -> (!llvm.ptr) // CHECK-NEXT: alloca {{.*}} addrspace(3) llvm.alloca %size x i32 {alignment = 0} : (i64) -> (!llvm.ptr) + // CHECK-NEXT: alloca inalloca {{.*}} align 4 + llvm.alloca inalloca %size x i32 : (i64) -> !llvm.ptr + // CHECK-NEXT: alloca inalloca {{.*}} align 8 + llvm.alloca inalloca %size x i32 {alignment = 8} : (i64) -> !llvm.ptr llvm.return }