Commit 2daadb78 by Jim Stichnoth

Subzero: Implement switch lowering for i64.

BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/701673002
parent f1156bec
......@@ -4030,14 +4030,38 @@ void TargetX8632::lowerSwitch(const InstSwitch *Inst) {
// cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default
Operand *Src0 = Inst->getComparison();
SizeT NumCases = Inst->getNumCases();
if (Src0->getType() == IceType_i64) {
Src0 = legalize(Src0); // get Base/Index into physical registers
Operand *Src0Lo = loOperand(Src0);
Operand *Src0Hi = hiOperand(Src0);
if (NumCases >= 2) {
Src0Lo = legalizeToVar(Src0Lo);
Src0Hi = legalizeToVar(Src0Hi);
} else {
Src0Lo = legalize(Src0Lo, Legal_Reg | Legal_Mem);
Src0Hi = legalize(Src0Hi, Legal_Reg | Legal_Mem);
}
for (SizeT I = 0; I < NumCases; ++I) {
Constant *ValueLo = Ctx->getConstantInt32(IceType_i32, Inst->getValue(I));
Constant *ValueHi =
Ctx->getConstantInt32(IceType_i32, Inst->getValue(I) >> 32);
InstX8632Label *Label = InstX8632Label::create(Func, this);
_cmp(Src0Lo, ValueLo);
_br(CondX86::Br_ne, Label);
_cmp(Src0Hi, ValueHi);
_br(CondX86::Br_e, Inst->getLabel(I));
Context.insert(Label);
}
_br(Inst->getLabelDefault());
return;
}
// OK, we'll be slightly less naive by forcing Src into a physical
// register if there are 2 or more uses.
if (NumCases >= 2)
Src0 = legalizeToVar(Src0, true);
Src0 = legalizeToVar(Src0);
else
Src0 = legalize(Src0, Legal_Reg | Legal_Mem);
for (SizeT I = 0; I < NumCases; ++I) {
// TODO(stichnot): Correct lowering for IceType_i64.
Constant *Value = Ctx->getConstantInt32(IceType_i32, Inst->getValue(I));
_cmp(Src0, Value);
_br(CondX86::Br_e, Inst->getLabel(I));
......
......@@ -2,7 +2,9 @@
; same label which also results in phi instructions with multiple
; entries for the same incoming edge.
; RUN: %p2i -i %s -a --verbose inst | FileCheck %s
; RUN: %p2i -i %s --args -O2 --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \
; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
; RUN: %p2i -i %s -a --verbose none | FileCheck --check-prefix=ERRORS %s
; RUN: %p2i -i %s --insts | %szdiff %s | FileCheck --check-prefix=DUMP %s
......@@ -51,6 +53,68 @@ sw.default:
; CHECK-LABEL: testSwitchImm
; CHECK-NOT: cmp {{[0-9]*}},
; Test for correct 64-bit lowering.
define internal i32 @testSwitch64(i64 %a) {
entry:
switch i64 %a, label %sw.default [
i64 123, label %return
i64 234, label %sw.bb1
i64 345, label %sw.bb2
i64 78187493520, label %sw.bb3
]
sw.bb1: ; preds = %entry
br label %return
sw.bb2: ; preds = %entry
br label %return
sw.bb3: ; preds = %entry
br label %return
sw.default: ; preds = %entry
br label %return
return: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %entry
%retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, %sw.bb1 ], [ 1, %entry ]
ret i32 %retval.0
}
; CHECK-LABEL: testSwitch64
; CHECK: cmp {{.*}}, 123
; CHECK-NEXT: jne
; CHECK-NEXT: cmp {{.*}}, 0
; CHECK-NEXT: je
; CHECK: cmp {{.*}}, 234
; CHECK-NEXT: jne
; CHECK-NEXT: cmp {{.*}}, 0
; CHECK-NEXT: je
; CHECK: cmp {{.*}}, 345
; CHECK-NEXT: jne
; CHECK-NEXT: cmp {{.*}}, 0
; CHECK-NEXT: je
; CHECK: cmp {{.*}}, 878082192
; CHECK-NEXT: jne
; CHECK-NEXT: cmp {{.*}}, 18
; CHECK-NEXT: je
; Similar to testSwitchImm, make sure proper addressing modes are
; used. In reality, this is tested by running the output through the
; assembler.
define i32 @testSwitchImm64() {
entry:
switch i64 10, label %sw.default [
i64 1, label %sw.default
]
sw.default:
ret i32 20
}
; CHECK-LABEL: testSwitchImm64
; CHECK: cmp {{.*}}, 1
; CHECK-NEXT: jne
; CHECK-NEXT: cmp {{.*}}, 0
; CHECK-NEXT: je
; CHECK-NOT: ICE translation error
; ERRORS-NOT: ICE translation error
; DUMP-NOT: SZ
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment