Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement integer compare in mips fast-isel
Summary: implement SelectCmp (integer compare ) in mips fast-isel Test Plan: icmpa.ll also ran 4 test-suite flavors mips32 r1/r2 O0/O2 Reviewers: dsanders Reviewed By: dsanders Subscribers: llvm-commits, rfuhler, mcrosier Differential Revision: http://reviews.llvm.org/D5566 llvm-svn: 219518
- Loading branch information
Reed Kotler
committed
Oct 10, 2014
1 parent
2beab5f
commit 497311a
Showing
2 changed files
with
302 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ | ||
; RUN: < %s | FileCheck %s | ||
; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32 \ | ||
; RUN: < %s | FileCheck %s | ||
|
||
@c = global i32 4, align 4 | ||
@d = global i32 9, align 4 | ||
@uc = global i32 4, align 4 | ||
@ud = global i32 9, align 4 | ||
@b1 = common global i32 0, align 4 | ||
|
||
; Function Attrs: nounwind | ||
define void @eq() { | ||
entry: | ||
; CHECK-LABEL: .ent eq | ||
|
||
%0 = load i32* @c, align 4 | ||
%1 = load i32* @d, align 4 | ||
%cmp = icmp eq i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_D_GOT:[0-9+]]], %got(d)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_C_GOT:[0-9+]]], %got(c)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_D:[0-9]+]], 0($[[REG_D_GOT]]) | ||
; CHECK-DAG: lw $[[REG_C:[0-9]+]], 0($[[REG_C_GOT]]) | ||
; CHECK: xor $[[REG1:[0-9]+]], $[[REG_C]], $[[REG_D]] | ||
; CHECK: sltiu $[[REG2:[0-9]+]], $[[REG1]], 1 | ||
; FIXME: This instruction is redundant. The sltiu can only produce 0 and 1. | ||
; CHECK: andi ${{[0-9]+}}, $[[REG2]], 1 | ||
|
||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @ne() { | ||
entry: | ||
; CHECK-LABEL: .ent ne | ||
%0 = load i32* @c, align 4 | ||
%1 = load i32* @d, align 4 | ||
%cmp = icmp ne i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_D_GOT:[0-9+]]], %got(d)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_C_GOT:[0-9+]]], %got(c)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_D:[0-9]+]], 0($[[REG_D_GOT]]) | ||
; CHECK-DAG: lw $[[REG_C:[0-9]+]], 0($[[REG_C_GOT]]) | ||
; CHECK: xor $[[REG1:[0-9]+]], $[[REG_C]], $[[REG_D]] | ||
; CHECK: sltu $[[REG2:[0-9]+]], $zero, $[[REG1]] | ||
; CHECK: andi ${{[0-9]+}}, $[[REG2]], 1 | ||
|
||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @ugt() { | ||
entry: | ||
; CHECK-LABEL: .ent ugt | ||
%0 = load i32* @uc, align 4 | ||
%1 = load i32* @ud, align 4 | ||
%cmp = icmp ugt i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_UD_GOT:[0-9+]]], %got(ud)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UC_GOT:[0-9+]]], %got(uc)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UD:[0-9]+]], 0($[[REG_UD_GOT]]) | ||
; CHECK-DAG: lw $[[REG_UC:[0-9]+]], 0($[[REG_UC_GOT]]) | ||
; CHECK: sltu $[[REG1:[0-9]+]], $[[REG_UD]], $[[REG_UC]] | ||
; CHECK: andi ${{[0-9]+}}, $[[REG1]], 1 | ||
|
||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @ult() { | ||
entry: | ||
; CHECK-LABEL: .ent ult | ||
%0 = load i32* @uc, align 4 | ||
%1 = load i32* @ud, align 4 | ||
%cmp = icmp ult i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_UD_GOT:[0-9+]]], %got(ud)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UC_GOT:[0-9+]]], %got(uc)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UD:[0-9]+]], 0($[[REG_UD_GOT]]) | ||
; CHECK-DAG: lw $[[REG_UC:[0-9]+]], 0($[[REG_UC_GOT]]) | ||
; CHECK: sltu $[[REG1:[0-9]+]], $[[REG_UC]], $[[REG_UD]] | ||
; CHECK: andi ${{[0-9]+}}, $[[REG1]], 1 | ||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @uge() { | ||
entry: | ||
; CHECK-LABEL: .ent uge | ||
%0 = load i32* @uc, align 4 | ||
%1 = load i32* @ud, align 4 | ||
%cmp = icmp uge i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_UD_GOT:[0-9+]]], %got(ud)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UC_GOT:[0-9+]]], %got(uc)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UD:[0-9]+]], 0($[[REG_UD_GOT]]) | ||
; CHECK-DAG: lw $[[REG_UC:[0-9]+]], 0($[[REG_UC_GOT]]) | ||
; CHECK: sltu $[[REG1:[0-9]+]], $[[REG_UC]], $[[REG_UD]] | ||
; CHECK: xori $[[REG2:[0-9]+]], $[[REG1]], 1 | ||
; CHECK: andi ${{[0-9]+}}, $[[REG2]], 1 | ||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @ule() { | ||
entry: | ||
; CHECK-LABEL: .ent ule | ||
%0 = load i32* @uc, align 4 | ||
%1 = load i32* @ud, align 4 | ||
%cmp = icmp ule i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_UD_GOT:[0-9+]]], %got(ud)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UC_GOT:[0-9+]]], %got(uc)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_UD:[0-9]+]], 0($[[REG_UD_GOT]]) | ||
; CHECK-DAG: lw $[[REG_UC:[0-9]+]], 0($[[REG_UC_GOT]]) | ||
; CHECK: sltu $[[REG1:[0-9]+]], $[[REG_UD]], $[[REG_UC]] | ||
; CHECK: xori $[[REG2:[0-9]+]], $[[REG1]], 1 | ||
; CHECK: andi ${{[0-9]+}}, $[[REG2]], 1 | ||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @sgt() { | ||
entry: | ||
; CHECK-LABEL: .ent sgt | ||
%0 = load i32* @c, align 4 | ||
%1 = load i32* @d, align 4 | ||
%cmp = icmp sgt i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_D_GOT:[0-9+]]], %got(d)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_C_GOT:[0-9+]]], %got(c)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_D:[0-9]+]], 0($[[REG_D_GOT]]) | ||
; CHECK-DAG: lw $[[REG_C:[0-9]+]], 0($[[REG_C_GOT]]) | ||
; CHECK: slt $[[REG1:[0-9]+]], $[[REG_D]], $[[REG_C]] | ||
; CHECK: andi ${{[0-9]+}}, $[[REG1]], 1 | ||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @slt() { | ||
entry: | ||
; CHECK-LABEL: .ent slt | ||
%0 = load i32* @c, align 4 | ||
%1 = load i32* @d, align 4 | ||
%cmp = icmp slt i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_D_GOT:[0-9+]]], %got(d)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_C_GOT:[0-9+]]], %got(c)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_D:[0-9]+]], 0($[[REG_D_GOT]]) | ||
; CHECK-DAG: lw $[[REG_C:[0-9]+]], 0($[[REG_C_GOT]]) | ||
; CHECK: slt $[[REG1:[0-9]+]], $[[REG_C]], $[[REG_D]] | ||
; CHECK: andi ${{[0-9]+}}, $[[REG1]], 1 | ||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @sge() { | ||
entry: | ||
; CHECK-LABEL: .ent sge | ||
%0 = load i32* @c, align 4 | ||
%1 = load i32* @d, align 4 | ||
%cmp = icmp sge i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
store i32 %conv, i32* @b1, align 4 | ||
; CHECK-DAG: lw $[[REG_D_GOT:[0-9+]]], %got(d)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_C_GOT:[0-9+]]], %got(c)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_D:[0-9]+]], 0($[[REG_D_GOT]]) | ||
; CHECK-DAG: lw $[[REG_C:[0-9]+]], 0($[[REG_C_GOT]]) | ||
; CHECK: slt $[[REG1:[0-9]+]], $[[REG_C]], $[[REG_D]] | ||
; CHECK: xori $[[REG2:[0-9]+]], $[[REG1]], 1 | ||
; CHECK: andi ${{[0-9]+}}, $[[REG2]], 1 | ||
ret void | ||
} | ||
|
||
; Function Attrs: nounwind | ||
define void @sle() { | ||
entry: | ||
; CHECK-LABEL: .ent sle | ||
%0 = load i32* @c, align 4 | ||
%1 = load i32* @d, align 4 | ||
%cmp = icmp sle i32 %0, %1 | ||
%conv = zext i1 %cmp to i32 | ||
; CHECK-DAG: lw $[[REG_D_GOT:[0-9+]]], %got(d)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_C_GOT:[0-9+]]], %got(c)(${{[0-9]+}}) | ||
; CHECK-DAG: lw $[[REG_D:[0-9]+]], 0($[[REG_D_GOT]]) | ||
; CHECK-DAG: lw $[[REG_C:[0-9]+]], 0($[[REG_C_GOT]]) | ||
; CHECK: slt $[[REG1:[0-9]+]], $[[REG_D]], $[[REG_C]] | ||
; CHECK: xori $[[REG2:[0-9]+]], $[[REG1]], 1 | ||
; CHECK: andi ${{[0-9]+}}, $[[REG2]], 1 | ||
store i32 %conv, i32* @b1, align 4 | ||
ret void | ||
} | ||
|
||
|