You've already forked linux-packaging-mono
							
							
		
			
	
	
		
			271 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
		
		
			
		
	
	
			271 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
|   | ; RUN: llc -O3 < %s | FileCheck %s
 | ||
|  | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64" | ||
|  | target triple = "arm64-unknown-unknown" | ||
|  | 
 | ||
|  | ; CHECK-LABEL: foo1
 | ||
|  | ; CHECK: cinc w{{[0-9]+}}, w{{[0-9]+}}, ne
 | ||
|  | define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp { | ||
|  | entry: | ||
|  |   %not.tobool = icmp ne i32 %c, 0 | ||
|  |   %add = zext i1 %not.tobool to i32 | ||
|  |   %b.add = add i32 %c, %b | ||
|  |   %add1 = add i32 %b.add, %add | ||
|  |   ret i32 %add1 | ||
|  | } | ||
|  | 
 | ||
|  | ; CHECK-LABEL: foo2
 | ||
|  | ; CHECK: cneg w{{[0-9]+}}, w{{[0-9]+}}, ne
 | ||
|  | define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp { | ||
|  | entry: | ||
|  |   %mul = sub i32 0, %b | ||
|  |   %tobool = icmp eq i32 %c, 0 | ||
|  |   %b.mul = select i1 %tobool, i32 %b, i32 %mul | ||
|  |   %add = add nsw i32 %b.mul, %c | ||
|  |   ret i32 %add | ||
|  | } | ||
|  | 
 | ||
|  | ; CHECK-LABEL: foo3
 | ||
|  | ; CHECK: cinv w{{[0-9]+}}, w{{[0-9]+}}, ne
 | ||
|  | define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp { | ||
|  | entry: | ||
|  |   %not.tobool = icmp ne i32 %c, 0 | ||
|  |   %xor = sext i1 %not.tobool to i32 | ||
|  |   %b.xor = xor i32 %xor, %b | ||
|  |   %add = add nsw i32 %b.xor, %c | ||
|  |   ret i32 %add | ||
|  | } | ||
|  | 
 | ||
|  | ; rdar://11632325
 | ||
|  | define i32@foo4(i32 %a) nounwind ssp { | ||
|  | ; CHECK-LABEL: foo4
 | ||
|  | ; CHECK: cneg
 | ||
|  | ; CHECK-NEXT: ret
 | ||
|  |   %cmp = icmp sgt i32 %a, -1 | ||
|  |   %neg = sub nsw i32 0, %a | ||
|  |   %cond = select i1 %cmp, i32 %a, i32 %neg | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i32@foo5(i32 %a, i32 %b) nounwind ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo5
 | ||
|  | ; CHECK: subs
 | ||
|  | ; CHECK-NEXT: cneg
 | ||
|  | ; CHECK-NEXT: ret
 | ||
|  |   %sub = sub nsw i32 %a, %b | ||
|  |   %cmp = icmp sgt i32 %sub, -1 | ||
|  |   %sub3 = sub nsw i32 0, %sub | ||
|  |   %cond = select i1 %cmp, i32 %sub, i32 %sub3 | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | ; make sure we can handle branch instruction in optimizeCompare.
 | ||
|  | define i32@foo6(i32 %a, i32 %b) nounwind ssp { | ||
|  | ; CHECK-LABEL: foo6
 | ||
|  | ; CHECK: b
 | ||
|  |   %sub = sub nsw i32 %a, %b | ||
|  |   %cmp = icmp sgt i32 %sub, 0 | ||
|  |   br i1 %cmp, label %l.if, label %l.else | ||
|  | 
 | ||
|  | l.if: | ||
|  |   ret i32 1 | ||
|  | 
 | ||
|  | l.else: | ||
|  |   ret i32 %sub | ||
|  | } | ||
|  | 
 | ||
|  | ; If CPSR is used multiple times and V flag is used, we don't remove cmp.
 | ||
|  | define i32 @foo7(i32 %a, i32 %b) nounwind { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo7:
 | ||
|  | ; CHECK: sub
 | ||
|  | ; CHECK-next: adds
 | ||
|  | ; CHECK-next: csneg
 | ||
|  | ; CHECK-next: b
 | ||
|  |   %sub = sub nsw i32 %a, %b | ||
|  |   %cmp = icmp sgt i32 %sub, -1 | ||
|  |   %sub3 = sub nsw i32 0, %sub | ||
|  |   %cond = select i1 %cmp, i32 %sub, i32 %sub3 | ||
|  |   br i1 %cmp, label %if.then, label %if.else | ||
|  | 
 | ||
|  | if.then: | ||
|  |   %cmp2 = icmp slt i32 %sub, -1 | ||
|  |   %sel = select i1 %cmp2, i32 %cond, i32 %a | ||
|  |   ret i32 %sel | ||
|  | 
 | ||
|  | if.else: | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo8:
 | ||
|  | ; CHECK: cmp w0, #0
 | ||
|  | ; CHECK: csinv w0, w1, w2, ne
 | ||
|  |   %tobool = icmp eq i32 %v, 0 | ||
|  |   %neg = xor i32 -1, %b | ||
|  |   %cond = select i1 %tobool, i32 %neg, i32 %a | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo9(i32 %v) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo9:
 | ||
|  | ; CHECK: cmp w0, #0
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
 | ||
|  | ; CHECK: cinv w0, w[[REG]], eq
 | ||
|  |   %tobool = icmp ne i32 %v, 0 | ||
|  |   %cond = select i1 %tobool, i32 4, i32 -5 | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo10(i64 %v) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo10:
 | ||
|  | ; CHECK: cmp x0, #0
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
 | ||
|  | ; CHECK: cinv x0, x[[REG]], eq
 | ||
|  |   %tobool = icmp ne i64 %v, 0 | ||
|  |   %cond = select i1 %tobool, i64 4, i64 -5 | ||
|  |   ret i64 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo11(i32 %v) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo11:
 | ||
|  | ; CHECK: cmp w0, #0
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
 | ||
|  | ; CHECK: cneg w0, w[[REG]], eq
 | ||
|  |   %tobool = icmp ne i32 %v, 0 | ||
|  |   %cond = select i1 %tobool, i32 4, i32 -4 | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo12(i64 %v) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo12:
 | ||
|  | ; CHECK: cmp x0, #0
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
 | ||
|  | ; CHECK: cneg x0, x[[REG]], eq
 | ||
|  |   %tobool = icmp ne i64 %v, 0 | ||
|  |   %cond = select i1 %tobool, i64 4, i64 -4 | ||
|  |   ret i64 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo13:
 | ||
|  | ; CHECK: cmp w0, #0
 | ||
|  | ; CHECK: csneg w0, w1, w2, ne
 | ||
|  |   %tobool = icmp eq i32 %v, 0 | ||
|  |   %sub = sub i32 0, %b | ||
|  |   %cond = select i1 %tobool, i32 %sub, i32 %a | ||
|  |   ret i32 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo14:
 | ||
|  | ; CHECK: cmp x0, #0
 | ||
|  | ; CHECK: csneg x0, x1, x2, ne
 | ||
|  |   %tobool = icmp eq i64 %v, 0 | ||
|  |   %sub = sub i64 0, %b | ||
|  |   %cond = select i1 %tobool, i64 %sub, i64 %a | ||
|  |   ret i64 %cond | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo15:
 | ||
|  | ; CHECK: cmp w0, w1
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
 | ||
|  | ; CHECK: cinc w0, w[[REG]], gt
 | ||
|  |   %cmp = icmp sgt i32 %a, %b | ||
|  |   %. = select i1 %cmp, i32 2, i32 1 | ||
|  |   ret i32 %. | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo16:
 | ||
|  | ; CHECK: cmp w0, w1
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
 | ||
|  | ; CHECK: cinc w0, w[[REG]], le
 | ||
|  |   %cmp = icmp sgt i32 %a, %b | ||
|  |   %. = select i1 %cmp, i32 1, i32 2 | ||
|  |   ret i32 %. | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo17:
 | ||
|  | ; CHECK: cmp x0, x1
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
 | ||
|  | ; CHECK: cinc x0, x[[REG]], gt
 | ||
|  |   %cmp = icmp sgt i64 %a, %b | ||
|  |   %. = select i1 %cmp, i64 2, i64 1 | ||
|  |   ret i64 %. | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo18:
 | ||
|  | ; CHECK: cmp x0, x1
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
 | ||
|  | ; CHECK: cinc x0, x[[REG]], le
 | ||
|  |   %cmp = icmp sgt i64 %a, %b | ||
|  |   %. = select i1 %cmp, i64 1, i64 2 | ||
|  |   ret i64 %. | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo19(i64 %a, i64 %b, i64 %c) { | ||
|  | entry: | ||
|  | ; CHECK-LABEL: foo19:
 | ||
|  | ; CHECK: cinc x0, x2
 | ||
|  | ; CHECK-NOT: add
 | ||
|  |   %cmp = icmp ult i64 %a, %b | ||
|  |   %inc = zext i1 %cmp to i64 | ||
|  |   %inc.c = add i64 %inc, %c | ||
|  |   ret i64 %inc.c | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo20(i32 %x) { | ||
|  | ; CHECK-LABEL: foo20:
 | ||
|  | ; CHECK: cmp w0, #5
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
 | ||
|  | ; CHECK: csinc w0, w[[REG]], wzr, eq
 | ||
|  |   %cmp = icmp eq i32 %x, 5 | ||
|  |   %res = select i1 %cmp, i32 6, i32 1 | ||
|  |   ret i32 %res | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo21(i64 %x) { | ||
|  | ; CHECK-LABEL: foo21:
 | ||
|  | ; CHECK: cmp x0, #5
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
 | ||
|  | ; CHECK: csinc x0, x[[REG]], xzr, eq
 | ||
|  |   %cmp = icmp eq i64 %x, 5 | ||
|  |   %res = select i1 %cmp, i64 6, i64 1 | ||
|  |   ret i64 %res | ||
|  | } | ||
|  | 
 | ||
|  | define i32 @foo22(i32 %x) { | ||
|  | ; CHECK-LABEL: foo22:
 | ||
|  | ; CHECK: cmp w0, #5
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
 | ||
|  | ; CHECK: csinc w0, w[[REG]], wzr, ne
 | ||
|  |   %cmp = icmp eq i32 %x, 5 | ||
|  |   %res = select i1 %cmp, i32 1, i32 6 | ||
|  |   ret i32 %res | ||
|  | } | ||
|  | 
 | ||
|  | define i64 @foo23(i64 %x) { | ||
|  | ; CHECK-LABEL: foo23:
 | ||
|  | ; CHECK: cmp x0, #5
 | ||
|  | ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
 | ||
|  | ; CHECK: csinc x0, x[[REG]], xzr, ne
 | ||
|  |   %cmp = icmp eq i64 %x, 5 | ||
|  |   %res = select i1 %cmp, i64 1, i64 6 | ||
|  |   ret i64 %res | ||
|  | } |