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 @@ -457,6 +457,11 @@ }]>]; let assemblyFormat = "operands attr-dict `:` type($condition) `,` type($res)"; } +def LLVM_FreezeOp : LLVM_OneResultOp<"freeze", [SameOperandsAndResultType]>, + Arguments<(ins LLVM_Type:$val)> { + let assemblyFormat = "$val attr-dict `:` type($val)"; + string llvmBuilder = "builder.CreateFreeze($val);"; +} // Terminators. def LLVM_BrOp : LLVM_TerminatorOp<"br", []> { diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -426,6 +426,12 @@ i->deleteValue(); return instMap[c] = instMap[i]; } + if (auto *ue = dyn_cast(c)) { + LLVMType type = processType(ue->getType()); + if (!type) + return nullptr; + return instMap[c] = bEntry.create(UnknownLoc::get(context), type); + } emitError(unknownLoc) << "unhandled constant: " << diag(*c); return nullptr; } @@ -493,7 +499,7 @@ // ICmp is handled specially. // FIXME: fcmp // PHI is handled specially. - INST(Call, Call), + INST(Freeze, Freeze), INST(Call, Call), // FIXME: select // FIXME: vaarg // FIXME: extractelement @@ -591,6 +597,7 @@ case llvm::Instruction::PtrToInt: case llvm::Instruction::IntToPtr: case llvm::Instruction::AddrSpaceCast: + case llvm::Instruction::Freeze: case llvm::Instruction::BitCast: { OperationState state(loc, opcMap.lookup(inst->getOpcode())); SmallVector ops; 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 @@ -282,3 +282,14 @@ ^bb4: llvm.return %0 : !llvm.i32 } + +// CHECK-LABEL: @useFreezeOp +func @useFreezeOp(%arg0: !llvm.i32) { + // CHECK: = llvm.freeze %[[ARG0:.*]] : !llvm.i32 + %0 = llvm.freeze %arg0 : !llvm.i32 + // CHECK: %[[x:.*]] = llvm.mlir.undef : !llvm.i8 + %1 = llvm.mlir.undef : !llvm.i8 + // CHECK: = llvm.freeze %[[x]] : !llvm.i8 + %2 = llvm.freeze %1 : !llvm.i8 + return +} \ No newline at end of file diff --git a/mlir/test/Target/import.ll b/mlir/test/Target/import.ll --- a/mlir/test/Target/import.ll +++ b/mlir/test/Target/import.ll @@ -297,3 +297,14 @@ ; CHECK: llvm.return %{{[0-9]+}} : !llvm.i32 ret i32 0 } + +;CHECK-LABEL: @useFreezeOp +define i32 @useFreezeOp(i32 %x) { + ;CHECK: %{{[0-9]+}} = llvm.freeze %{{[0-9a-z]+}} : !llvm.i32 + %1 = freeze i32 %x + %2 = add i8 10, 10 + ;CHECK: %{{[0-9]+}} = llvm.freeze %{{[0-9]+}} : !llvm.i8 + %3 = freeze i8 %2 + %poison = add nsw i1 0, undef + ret i32 0 +} \ No newline at end of file diff --git a/mlir/test/Target/llvmir.mlir b/mlir/test/Target/llvmir.mlir --- a/mlir/test/Target/llvmir.mlir +++ b/mlir/test/Target/llvmir.mlir @@ -1171,3 +1171,13 @@ ^bb3: // pred: ^bb1 %8 = llvm.invoke @bar(%6) to ^bb2 unwind ^bb1 : (!llvm<"i8*">) -> !llvm<"i8*"> } + +// CHECK-LABEL: @callFreezeOp +llvm.func @callFreezeOp(%x : !llvm.i32) { + // CHECK: freeze i32 %{{[0-9]+}} + %0 = llvm.freeze %x : !llvm.i32 + %1 = llvm.mlir.undef : !llvm.i32 + // CHECK: freeze i32 undef + %2 = llvm.freeze %1 : !llvm.i32 + llvm.return +} \ No newline at end of file