[mlir][LLVMIR] Add support for translating insert/extractvalue

Add support for translating llvm::InsertValue and llvm::ExtractValue.

Differential Revision: https://reviews.llvm.org/D125028
This commit is contained in:
Min-Yih Hsu 2022-04-20 19:57:06 -07:00
parent 5a19fbad83
commit b8f52c08f8
2 changed files with 68 additions and 2 deletions

View File

@ -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<llvm::InsertValueInst>(inst);
Value inserted = processValue(ivInst->getInsertedValueOperand());
if (!inserted)
return failure();
Value aggOperand = processValue(ivInst->getAggregateOperand());
if (!aggOperand)
return failure();
SmallVector<int32_t> idxValues;
for (unsigned idx : ivInst->getIndices())
idxValues.push_back(static_cast<int32_t>(idx));
ArrayAttr indices = b.getI32ArrayAttr(idxValues);
instMap[inst] = b.create<InsertValueOp>(loc, aggOperand, inserted, indices);
return success();
}
case llvm::Instruction::ExtractValue: {
auto *evInst = cast<llvm::ExtractValueInst>(inst);
Value aggOperand = processValue(evInst->getAggregateOperand());
if (!aggOperand)
return failure();
Type type = processType(inst->getType());
if (!type)
return failure();
SmallVector<int32_t> idxValues;
for (unsigned idx : evInst->getIndices())
idxValues.push_back(static_cast<int32_t>(idx));
ArrayAttr indices = b.getI32ArrayAttr(idxValues);
instMap[inst] = b.create<ExtractValueOp>(loc, type, aggOperand, indices);
return success();
}
}
}

View File

@ -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
}