From b8f52c08f85aac47cb2079a7a80a9d88875e0692 Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Wed, 20 Apr 2022 19:57:06 -0700 Subject: [PATCH] [mlir][LLVMIR] Add support for translating insert/extractvalue Add support for translating llvm::InsertValue and llvm::ExtractValue. Differential Revision: https://reviews.llvm.org/D125028 --- mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp | 39 +++++++++++++++++++- mlir/test/Target/LLVMIR/Import/basic.ll | 31 ++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp index c6f7b3e76a14..00f850c5278a 100644 --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -619,8 +619,8 @@ static StringRef lookupOperationNameFromOpcode(unsigned opcode) { // FIXME: extractelement // FIXME: insertelement // FIXME: shufflevector - // FIXME: extractvalue - // FIXME: insertvalue + // InsertValue is handled specially. + // ExtractValue is handled specially. // FIXME: landingpad }; #undef INST @@ -1031,6 +1031,41 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) { dynamicIndices, staticIndices); return success(); } + case llvm::Instruction::InsertValue: { + auto *ivInst = cast(inst); + Value inserted = processValue(ivInst->getInsertedValueOperand()); + if (!inserted) + return failure(); + Value aggOperand = processValue(ivInst->getAggregateOperand()); + if (!aggOperand) + return failure(); + + SmallVector idxValues; + for (unsigned idx : ivInst->getIndices()) + idxValues.push_back(static_cast(idx)); + ArrayAttr indices = b.getI32ArrayAttr(idxValues); + + instMap[inst] = b.create(loc, aggOperand, inserted, indices); + return success(); + } + case llvm::Instruction::ExtractValue: { + auto *evInst = cast(inst); + Value aggOperand = processValue(evInst->getAggregateOperand()); + if (!aggOperand) + return failure(); + + Type type = processType(inst->getType()); + if (!type) + return failure(); + + SmallVector idxValues; + for (unsigned idx : evInst->getIndices()) + idxValues.push_back(static_cast(idx)); + ArrayAttr indices = b.getI32ArrayAttr(idxValues); + + instMap[inst] = b.create(loc, type, aggOperand, indices); + return success(); + } } } diff --git a/mlir/test/Target/LLVMIR/Import/basic.ll b/mlir/test/Target/LLVMIR/Import/basic.ll index 62f11fd87ffa..d5a766738803 100644 --- a/mlir/test/Target/LLVMIR/Import/basic.ll +++ b/mlir/test/Target/LLVMIR/Import/basic.ll @@ -541,3 +541,34 @@ def: ; pred: bb3, bbs call void @g(i32 %v2) ret void } + +; Insert/ExtractValue +; CHECK-LABEL: llvm.func @insert_extract_value_struct +define float @insert_extract_value_struct({{i32},{float, double}}* %p) { + ; CHECK: %[[C0:.+]] = llvm.mlir.constant(2.000000e+00 : f64) + ; CHECK: %[[VT:.+]] = llvm.load %{{.+}} + %t = load {{i32},{float, double}}, {{i32},{float, double}}* %p + ; CHECK: %[[EV:.+]] = llvm.extractvalue %[[VT]][1 : i32, 0 : i32] : + ; CHECK-SAME: !llvm.struct<(struct<(i32)>, struct<(f32, f64)>)> + %s = extractvalue {{i32},{float, double}} %t, 1, 0 + ; CHECK: %[[IV:.+]] = llvm.insertvalue %[[C0]], %[[VT]][1 : i32, 1 : i32] : + ; CHECK-SAME: !llvm.struct<(struct<(i32)>, struct<(f32, f64)>)> + %r = insertvalue {{i32},{float, double}} %t, double 2.0, 1, 1 + ; CHECK: llvm.store %[[IV]], %{{.+}} + store {{i32},{float, double}} %r, {{i32},{float, double}}* %p + ; CHECK: llvm.return %[[EV]] + ret float %s +} + +; CHECK-LABEL: llvm.func @insert_extract_value_array +define void @insert_extract_value_array([4 x [4 x i8]] %x1) { + ; CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i8) + ; CHECK: llvm.insertvalue %[[C0]], %{{.+}}[0 : i32, 0 : i32] : !llvm.array<4 x array<4 x i8>> + %res1 = insertvalue [4 x [4 x i8 ]] %x1, i8 0, 0, 0 + ; CHECK: llvm.extractvalue %{{.+}}[1 : i32] : !llvm.array<4 x array<4 x i8>> + %res2 = extractvalue [4 x [4 x i8 ]] %x1, 1 + ; CHECK: llvm.extractvalue %{{.+}}[0 : i32, 1 : i32] : !llvm.array<4 x array<4 x i8>> + %res3 = extractvalue [4 x [4 x i8 ]] %x1, 0, 1 + ret void +} +