211 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; RUN: llc -march=mipsel -relocation-model=pic -O0 -fast-isel-abort=1 -mcpu=mips32r2 \
 | |
| ; RUN:     < %s | FileCheck %s
 | |
| ; RUN: llc -march=mipsel -relocation-model=pic -O0 -fast-isel-abort=1 -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, i32* @c, align 4
 | |
|   %1 = load i32, 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, i32* @c, align 4
 | |
|   %1 = load i32, 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]]
 | |
| ; FIXME: This instruction is redundant. The sltu 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 @ugt()  {
 | |
| entry:
 | |
| ; CHECK-LABEL:  .ent  ugt
 | |
|   %0 = load i32, i32* @uc, align 4
 | |
|   %1 = load i32, 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]]
 | |
| ; FIXME: This instruction is redundant. The sltu can only produce 0 and 1.
 | |
| ; 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, i32* @uc, align 4
 | |
|   %1 = load i32, 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]]
 | |
| ; FIXME: This instruction is redundant. The sltu can only produce 0 and 1.
 | |
| ; 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, i32* @uc, align 4
 | |
|   %1 = load i32, 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
 | |
| ; FIXME: This instruction is redundant. The sltu 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 @ule()  {
 | |
| entry:
 | |
| ; CHECK-LABEL:  .ent  ule
 | |
|   %0 = load i32, i32* @uc, align 4
 | |
|   %1 = load i32, 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
 | |
| ; FIXME: This instruction is redundant. The sltu 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 @sgt()  {
 | |
| entry:
 | |
| ; CHECK-LABEL:  .ent sgt
 | |
|   %0 = load i32, i32* @c, align 4
 | |
|   %1 = load i32, 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]]
 | |
| ; FIXME: This instruction is redundant. The slt can only produce 0 and 1.
 | |
| ; 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, i32* @c, align 4
 | |
|   %1 = load i32, 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]]
 | |
| ; FIXME: This instruction is redundant. The slt can only produce 0 and 1.
 | |
| ; 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, i32* @c, align 4
 | |
|   %1 = load i32, 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
 | |
| ; FIXME: This instruction is redundant. The slt can only produce 0 and 1.
 | |
| ; CHECK:  andi  ${{[0-9]+}}, $[[REG2]], 1
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| ; Function Attrs: nounwind
 | |
| define void @sle()  {
 | |
| entry:
 | |
| ; CHECK-LABEL:  .ent sle
 | |
|   %0 = load i32, i32* @c, align 4
 | |
|   %1 = load i32, 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
 | |
| ; FIXME: This instruction is redundant. The slt can only produce 0 and 1.
 | |
| ; CHECK:        andi    ${{[0-9]+}}, $[[REG2]], 1
 | |
|   store i32 %conv, i32* @b1, align 4
 | |
|   ret void
 | |
| }
 |