135 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=generic | FileCheck %s
 | |
| 
 | |
| ; Check that we recognize this idiom for rotation too:
 | |
| ;    a << (b & (OpSize-1)) | a >> ((0 - b) & (OpSize-1))
 | |
| 
 | |
| define i32 @rotate_left_32(i32 %a, i32 %b) {
 | |
| ; CHECK-LABEL: rotate_left_32:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: roll
 | |
| entry:
 | |
|   %and = and i32 %b, 31
 | |
|   %shl = shl i32 %a, %and
 | |
|   %0 = sub i32 0, %b
 | |
|   %and3 = and i32 %0, 31
 | |
|   %shr = lshr i32 %a, %and3
 | |
|   %or = or i32 %shl, %shr
 | |
|   ret i32 %or
 | |
| }
 | |
| 
 | |
| define i32 @rotate_right_32(i32 %a, i32 %b) {
 | |
| ; CHECK-LABEL: rotate_right_32:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: rorl
 | |
| entry:
 | |
|   %and = and i32 %b, 31
 | |
|   %shl = lshr i32 %a, %and
 | |
|   %0 = sub i32 0, %b
 | |
|   %and3 = and i32 %0, 31
 | |
|   %shr = shl i32 %a, %and3
 | |
|   %or = or i32 %shl, %shr
 | |
|   ret i32 %or
 | |
| }
 | |
| 
 | |
| define i64 @rotate_left_64(i64 %a, i64 %b) {
 | |
| ; CHECK-LABEL: rotate_left_64:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: rolq
 | |
| entry:
 | |
|   %and = and i64 %b, 63
 | |
|   %shl = shl i64 %a, %and
 | |
|   %0 = sub i64 0, %b
 | |
|   %and3 = and i64 %0, 63
 | |
|   %shr = lshr i64 %a, %and3
 | |
|   %or = or i64 %shl, %shr
 | |
|   ret i64 %or
 | |
| }
 | |
| 
 | |
| define i64 @rotate_right_64(i64 %a, i64 %b) {
 | |
| ; CHECK-LABEL: rotate_right_64:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: rorq
 | |
| entry:
 | |
|   %and = and i64 %b, 63
 | |
|   %shl = lshr i64 %a, %and
 | |
|   %0 = sub i64 0, %b
 | |
|   %and3 = and i64 %0, 63
 | |
|   %shr = shl i64 %a, %and3
 | |
|   %or = or i64 %shl, %shr
 | |
|   ret i64 %or
 | |
| }
 | |
| 
 | |
| ; Also check mem operand.
 | |
| 
 | |
| define void @rotate_left_m32(i32 *%pa, i32 %b) {
 | |
| ; CHECK-LABEL: rotate_left_m32:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: roll
 | |
| ; no store:
 | |
| ; CHECK-NOT: mov
 | |
| entry:
 | |
|   %a = load i32, i32* %pa, align 16
 | |
|   %and = and i32 %b, 31
 | |
|   %shl = shl i32 %a, %and
 | |
|   %0 = sub i32 0, %b
 | |
|   %and3 = and i32 %0, 31
 | |
|   %shr = lshr i32 %a, %and3
 | |
|   %or = or i32 %shl, %shr
 | |
|   store i32 %or, i32* %pa, align 32
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @rotate_right_m32(i32 *%pa, i32 %b) {
 | |
| ; CHECK-LABEL: rotate_right_m32:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: rorl
 | |
| ; no store:
 | |
| ; CHECK-NOT: mov
 | |
| entry:
 | |
|   %a = load i32, i32* %pa, align 16
 | |
|   %and = and i32 %b, 31
 | |
|   %shl = lshr i32 %a, %and
 | |
|   %0 = sub i32 0, %b
 | |
|   %and3 = and i32 %0, 31
 | |
|   %shr = shl i32 %a, %and3
 | |
|   %or = or i32 %shl, %shr
 | |
|   store i32 %or, i32* %pa, align 32
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @rotate_left_m64(i64 *%pa, i64 %b) {
 | |
| ; CHECK-LABEL: rotate_left_m64:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: rolq
 | |
| ; no store:
 | |
| ; CHECK-NOT: mov
 | |
| entry:
 | |
|   %a = load i64, i64* %pa, align 16
 | |
|   %and = and i64 %b, 63
 | |
|   %shl = shl i64 %a, %and
 | |
|   %0 = sub i64 0, %b
 | |
|   %and3 = and i64 %0, 63
 | |
|   %shr = lshr i64 %a, %and3
 | |
|   %or = or i64 %shl, %shr
 | |
|   store i64 %or, i64* %pa, align 64
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @rotate_right_m64(i64 *%pa, i64 %b) {
 | |
| ; CHECK-LABEL: rotate_right_m64:
 | |
| ; CHECK-NOT: and
 | |
| ; CHECK: rorq
 | |
| ; no store:
 | |
| ; CHECK-NOT: mov
 | |
| entry:
 | |
|   %a = load i64, i64* %pa, align 16
 | |
|   %and = and i64 %b, 63
 | |
|   %shl = lshr i64 %a, %and
 | |
|   %0 = sub i64 0, %b
 | |
|   %and3 = and i64 %0, 63
 | |
|   %shr = shl i64 %a, %and3
 | |
|   %or = or i64 %shl, %shr
 | |
|   store i64 %or, i64* %pa, align 64
 | |
|   ret void
 | |
| }
 |