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 @@ -619,8 +619,8 @@ // 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 @@ 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 --- a/mlir/test/Target/LLVMIR/Import/basic.ll +++ b/mlir/test/Target/LLVMIR/Import/basic.ll @@ -541,3 +541,34 @@ 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 +} +