[Mlir-commits] [mlir] 857eb4a - [mlir][LLVMIR] Add support for translating Switch instruction
Min-Yih Hsu
llvmlistbot at llvm.org
Tue May 3 09:42:38 PDT 2022
Author: Min-Yih Hsu
Date: 2022-05-03T09:41:40-07:00
New Revision: 857eb4a152cf3386db5f2070751586829a9d67ff
URL: https://github.com/llvm/llvm-project/commit/857eb4a152cf3386db5f2070751586829a9d67ff
DIFF: https://github.com/llvm/llvm-project/commit/857eb4a152cf3386db5f2070751586829a9d67ff.diff
LOG: [mlir][LLVMIR] Add support for translating Switch instruction
Add support for translating llvm::SwitchInst.
Differential Revision: https://reviews.llvm.org/D124628
Added:
Modified:
mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
mlir/test/Target/LLVMIR/Import/basic.ll
Removed:
################################################################################
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index 1a734561fbef7..ed4b70dfed0a3 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -583,7 +583,7 @@ static StringRef lookupOperationNameFromOpcode(unsigned opcode) {
static const DenseMap<unsigned, StringRef> opcMap = {
// Ret is handled specially.
// Br is handled specially.
- // FIXME: switch
+ // Switch is handled specially.
// FIXME: indirectbr
// FIXME: invoke
INST(Resume, Resume),
@@ -858,6 +858,40 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
b.create(state);
return success();
}
+ case llvm::Instruction::Switch: {
+ auto *swInst = cast<llvm::SwitchInst>(inst);
+ // Process the condition value.
+ Value condition = processValue(swInst->getCondition());
+ if (!condition)
+ return failure();
+
+ SmallVector<Value> defaultBlockArgs;
+ // Process the default case.
+ llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
+ if (failed(processBranchArgs(swInst, defaultBB, defaultBlockArgs)))
+ return failure();
+
+ // Process the cases.
+ unsigned numCases = swInst->getNumCases();
+ SmallVector<SmallVector<Value>> caseOperands(numCases);
+ SmallVector<ValueRange> caseOperandRefs(numCases);
+ SmallVector<int32_t> caseValues(numCases);
+ SmallVector<Block *> caseBlocks(numCases);
+ for (const auto &en : llvm::enumerate(swInst->cases())) {
+ const llvm::SwitchInst::CaseHandle &caseHandle = en.value();
+ unsigned i = en.index();
+ llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
+ if (failed(processBranchArgs(swInst, succBB, caseOperands[i])))
+ return failure();
+ caseOperandRefs[i] = caseOperands[i];
+ caseValues[i] = caseHandle.getCaseValue()->getSExtValue();
+ caseBlocks[i] = blocks[succBB];
+ }
+
+ b.create<SwitchOp>(loc, condition, blocks[defaultBB], defaultBlockArgs,
+ caseValues, caseBlocks, caseOperandRefs);
+ return success();
+ }
case llvm::Instruction::PHI: {
Type type = processType(inst->getType());
if (!type)
diff --git a/mlir/test/Target/LLVMIR/Import/basic.ll b/mlir/test/Target/LLVMIR/Import/basic.ll
index 8b77c69e0c82b..62f11fd87ffa0 100644
--- a/mlir/test/Target/LLVMIR/Import/basic.ll
+++ b/mlir/test/Target/LLVMIR/Import/basic.ll
@@ -435,3 +435,109 @@ define i32 @useFenceInst() {
fence syncscope("") seq_cst
ret i32 0
}
+
+; Switch instruction
+declare void @g(i32)
+
+; CHECK-LABEL: llvm.func @simple_switch(%arg0: i32) {
+define void @simple_switch(i32 %val) {
+; CHECK: %[[C0:.+]] = llvm.mlir.constant(11 : i32) : i32
+; CHECK: %[[C1:.+]] = llvm.mlir.constant(87 : i32) : i32
+; CHECK: %[[C2:.+]] = llvm.mlir.constant(78 : i32) : i32
+; CHECK: %[[C3:.+]] = llvm.mlir.constant(94 : i32) : i32
+; CHECK: %[[C4:.+]] = llvm.mlir.constant(1 : i32) : i32
+; CHECK: llvm.switch %arg0 : i32, ^[[BB5:.+]] [
+; CHECK: 0: ^[[BB1:.+]],
+; CHECK: 9: ^[[BB2:.+]],
+; CHECK: 994: ^[[BB3:.+]],
+; CHECK: 1154: ^[[BB4:.+]]
+; CHECK: ]
+ switch i32 %val, label %def [
+ i32 0, label %one
+ i32 9, label %two
+ i32 994, label %three
+ i32 1154, label %four
+ ]
+
+; CHECK: ^[[BB1]]:
+; CHECK: llvm.call @g(%[[C4]]) : (i32) -> ()
+; CHECK: llvm.return
+one:
+ call void @g(i32 1)
+ ret void
+; CHECK: ^[[BB2]]:
+; CHECK: llvm.call @g(%[[C3]]) : (i32) -> ()
+; CHECK: llvm.return
+two:
+ call void @g(i32 94)
+ ret void
+; CHECK: ^[[BB3]]:
+; CHECK: llvm.call @g(%[[C2]]) : (i32) -> ()
+; CHECK: llvm.return
+three:
+ call void @g(i32 78)
+ ret void
+; CHECK: ^[[BB4]]:
+; CHECK: llvm.call @g(%[[C1]]) : (i32) -> ()
+; CHECK: llvm.return
+four:
+ call void @g(i32 87)
+ ret void
+; CHECK: ^[[BB5]]:
+; CHECK: llvm.call @g(%[[C0]]) : (i32) -> ()
+; CHECK: llvm.return
+def:
+ call void @g(i32 11)
+ ret void
+}
+
+; CHECK-LABEL: llvm.func @switch_args(%arg0: i32) {
+define void @switch_args(i32 %val) {
+ ; CHECK: %[[C0:.+]] = llvm.mlir.constant(44 : i32) : i32
+ ; CHECK: %[[C1:.+]] = llvm.mlir.constant(34 : i32) : i32
+ ; CHECK: %[[C2:.+]] = llvm.mlir.constant(33 : i32) : i32
+ %pred = icmp ult i32 %val, 87
+ br i1 %pred, label %bbs, label %bb1
+
+bb1:
+ %vx = add i32 %val, 22
+ %pred2 = icmp ult i32 %val, 94
+ br i1 %pred2, label %bb2, label %bb3
+
+bb2:
+ %vx0 = add i32 %val, 23
+ br label %one
+
+bb3:
+ br label %def
+
+; CHECK: %[[V1:.+]] = llvm.add %arg0, %[[C2]] : i32
+; CHECK: %[[V2:.+]] = llvm.add %arg0, %[[C1]] : i32
+; CHECK: %[[V3:.+]] = llvm.add %arg0, %[[C0]] : i32
+; CHECK: llvm.switch %arg0 : i32, ^[[BBD:.+]](%[[V3]] : i32) [
+; CHECK: 0: ^[[BB1:.+]](%[[V1]], %[[V2]] : i32, i32)
+; CHECK: ]
+bbs:
+ %vy = add i32 %val, 33
+ %vy0 = add i32 %val, 34
+ %vz = add i32 %val, 44
+ switch i32 %val, label %def [
+ i32 0, label %one
+ ]
+
+; CHECK: ^[[BB1]](%[[BA0:.+]]: i32, %[[BA1:.+]]: i32):
+one: ; pred: bb2, bbs
+ %v0 = phi i32 [%vx, %bb2], [%vy, %bbs]
+ %v1 = phi i32 [%vx0, %bb2], [%vy0, %bbs]
+ ; CHECK: llvm.add %[[BA0]], %[[BA1]] : i32
+ %vf = add i32 %v0, %v1
+ call void @g(i32 %vf)
+ ret void
+
+; CHECK: ^[[BBD]](%[[BA2:.+]]: i32):
+def: ; pred: bb3, bbs
+ %v2 = phi i32 [%vx, %bb3], [%vz, %bbs]
+ ; CHECK: llvm.call @g(%[[BA2]])
+ call void @g(i32 %v2)
+ ret void
+}
More information about the Mlir-commits
mailing list