Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
test/CodeGen/X86/shift-double-x86_64.ll
Show First 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
; CHECK-NEXT: retq | ; CHECK-NEXT: retq | ||||
%bits64 = xor i64 %bits, 63 | %bits64 = xor i64 %bits, 63 | ||||
%lo2 = add i64 %lo, %lo | %lo2 = add i64 %lo, %lo | ||||
%sh_lo = shl i64 %lo2, %bits64 | %sh_lo = shl i64 %lo2, %bits64 | ||||
%sh_hi = lshr i64 %hi, %bits | %sh_hi = lshr i64 %hi, %bits | ||||
%sh = or i64 %sh_lo, %sh_hi | %sh = or i64 %sh_lo, %sh_hi | ||||
ret i64 %sh | ret i64 %sh | ||||
} | } | ||||
;------------------------------------------------------------------------------------- | |||||
; double shift left pattern | |||||
;uint_t shld(uint_t a, uint_t b, int shift) | |||||
;{ | |||||
; return (a << shift) | (b >> (sizeof(uint_t)*8 - shift)); | |||||
;} | |||||
RKSimon: Most of these tests should probably be in shift-double.ll (tested on 32 and 64bit targets) and… | |||||
define i64 @shld64_sh64(i64 %a, i64 %b, i64 %bits) nounwind { | |||||
; CHECK-LABEL: shld64_sh64: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%shl = shl i64 %a, %bits | |||||
%sub = sub i64 64, %bits | |||||
%shr = lshr i64 %b, %sub | |||||
%or = or i64 %shr, %shl | |||||
ret i64 %or | |||||
} | |||||
define i64 @shld64_sh32(i64 %a, i64 %b, i32 %bits) nounwind { | |||||
; CHECK-LABEL: shld64_sh32: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i32 %bits to i64 | |||||
%shl = shl i64 %a, %sh_prom | |||||
%sub = sub nsw i64 64, %sh_prom | |||||
%shr = lshr i64 %b, %sub | |||||
%or = or i64 %shr, %shl | |||||
ret i64 %or | |||||
} | |||||
define i64 @shld64_sh16(i64 %a, i64 %b, i16 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shld64_sh16: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i16 %bits to i64 | |||||
%shl = shl i64 %a, %sh_prom | |||||
%sub = sub nsw i64 64, %sh_prom | |||||
%shr = lshr i64 %b, %sub | |||||
%or = or i64 %shr, %shl | |||||
ret i64 %or | |||||
} | |||||
define i64 @shld64_sh8(i64 %a, i64 %b, i8 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shld64_sh8: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i8 %bits to i64 | |||||
%shl = shl i64 %a, %sh_prom | |||||
%sub = sub nsw i64 64, %sh_prom | |||||
%shr = lshr i64 %b, %sub | |||||
%or = or i64 %shr, %shl | |||||
ret i64 %or | |||||
} | |||||
;------------------------------------------------------------------------------------- | |||||
; double shift right pattern | |||||
;uint_t shrd(uint_t a, uint_t b, int shift) | |||||
;{ | |||||
; return (a >> shift) | (b << ( sizeof(uint_t)*8 - shift)); | |||||
;} | |||||
define i64 @shrd64_sh64(i64 %a, i64 %b, i64 %bits) nounwind { | |||||
; CHECK-LABEL: shrd64_sh64: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%shr = lshr i64 %a, %bits | |||||
%sub = sub i64 64, %bits | |||||
%shl = shl i64 %b, %sub | |||||
%or = or i64 %shl, %shr | |||||
ret i64 %or | |||||
} | |||||
define i64 @shrd64_sh32(i64 %a, i64 %b, i32 %bits) nounwind { | |||||
; CHECK-LABEL: shrd64_sh32: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i32 %bits to i64 | |||||
%shr = lshr i64 %a, %sh_prom | |||||
%sub = sub nsw i64 64, %sh_prom | |||||
%shl = shl i64 %b, %sub | |||||
%or = or i64 %shl, %shr | |||||
ret i64 %or | |||||
} | |||||
define i64 @shrd64_sh16(i64 %a, i64 %b, i16 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shrd64_sh16: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i16 %bits to i64 | |||||
%shr = lshr i64 %a, %sh_prom | |||||
%sub = sub nsw i64 64, %sh_prom | |||||
%shl = shl i64 %b, %sub | |||||
%or = or i64 %shl, %shr | |||||
ret i64 %or | |||||
} | |||||
define i64 @shrd64_sh8(i64 %a, i64 %b, i8 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shrd64_sh8: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i8 %bits to i64 | |||||
%shr = lshr i64 %a, %sh_prom | |||||
%sub = sub nsw i64 64, %sh_prom | |||||
%shl = shl i64 %b, %sub | |||||
%or = or i64 %shl, %shr | |||||
ret i64 %or | |||||
} | |||||
;------------------------------------------------------------------------------------- | |||||
; double shift left with xor pattern | |||||
;uint64_t shldx(uint64_t a, uint64_t b, shift_t bits) | |||||
;{ | |||||
; return (a << bits) | ((b >> 1) >> (bits ^ (sizeof(a)*8 - 1))); | |||||
;} | |||||
define i64 @shld64x_sh64(i64 %a, i64 %b, i64 %bits) nounwind { | |||||
; CHECK-LABEL: shld64x_sh64: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%shl = shl i64 %a, %bits | |||||
%shr = lshr i64 %b, 1 | |||||
%xor = xor i64 %bits, 63 | |||||
%shr1 = lshr i64 %shr, %xor | |||||
%or = or i64 %shr1, %shl | |||||
ret i64 %or | |||||
} | |||||
define i64 @shld64x_sh32(i64 %a, i64 %b, i32 %bits) nounwind { | |||||
; CHECK-LABEL: shld64x_sh32: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i32 %bits to i64 | |||||
%shl = shl i64 %a, %sh_prom | |||||
%shr = lshr i64 %b, 1 | |||||
%xor = xor i64 %sh_prom, 63 | |||||
%shr1 = lshr i64 %shr, %xor | |||||
%or = or i64 %shr1, %shl | |||||
ret i64 %or | |||||
} | |||||
define i64 @shld64x_sh16(i64 %a, i64 %b, i16 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shld64x_sh16: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i16 %bits to i64 | |||||
%shl = shl i64 %a, %sh_prom | |||||
%shr = lshr i64 %b, 1 | |||||
%xor0 = xor i16 %bits, 63 | |||||
%xor = zext i16 %xor0 to i64 | |||||
%shr2 = lshr i64 %shr, %xor | |||||
%or = or i64 %shr2, %shl | |||||
ret i64 %or | |||||
} | |||||
define i64 @shld64x_sh8(i64 %a, i64 %b, i8 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shld64x_sh8: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shldq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i8 %bits to i64 | |||||
%shl = shl i64 %a, %sh_prom | |||||
%shr = lshr i64 %b, 1 | |||||
%xor0 = xor i8 %bits, 63 | |||||
%xor = zext i8 %xor0 to i64 | |||||
%shr2 = lshr i64 %shr, %xor | |||||
%or = or i64 %shr2, %shl | |||||
ret i64 %or | |||||
} | |||||
;------------------------------------------------------------------------------------- | |||||
; double shift right with xor pattern | |||||
;uint64_t shrdx(uint64_t a, uint64_t b, shift_t bits) | |||||
;{ | |||||
; return (a >> bits) | ((b << 1) << (bits ^ (sizeof(a)*8 - 1))); | |||||
;} | |||||
define i64 @shrd64x_sh64(i64 %a, i64 %b, i64 %bits) nounwind { | |||||
; CHECK-LABEL: shrd64x_sh64: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%shr = lshr i64 %a, %bits | |||||
%shl = shl i64 %b, 1 | |||||
%xor = xor i64 %bits, 63 | |||||
%shl1 = shl i64 %shl, %xor | |||||
%or = or i64 %shl1, %shr | |||||
ret i64 %or | |||||
} | |||||
define i64 @shrd64x_sh32(i64 %a, i64 %b, i32 %bits) nounwind { | |||||
; CHECK-LABEL: shrd64x_sh32: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i32 %bits to i64 | |||||
%shr = lshr i64 %a, %sh_prom | |||||
%shl = shl i64 %b, 1 | |||||
%xor = xor i64 %sh_prom, 63 | |||||
%shl1 = shl i64 %shl, %xor | |||||
%or = or i64 %shl1, %shr | |||||
ret i64 %or | |||||
} | |||||
define i64 @shrd64x_sh16(i64 %a, i64 %b, i16 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shrd64x_sh16: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i16 %bits to i64 | |||||
%shr = lshr i64 %a, %sh_prom | |||||
%shl = shl i64 %b, 1 | |||||
%xor0 = xor i16 %bits, 63 | |||||
%xor = zext i16 %xor0 to i64 | |||||
%shl2 = shl i64 %shl, %xor | |||||
%or = or i64 %shl2, %shr | |||||
ret i64 %or | |||||
} | |||||
define i64 @shrd64x_sh8(i64 %a, i64 %b, i8 zeroext %bits) nounwind { | |||||
; CHECK-LABEL: shrd64x_sh8: | |||||
; CHECK: movl %edx, %ecx | |||||
; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |||||
; CHECK-NEXT: movq %rdi, %rax | |||||
; CHECK: retq | |||||
%sh_prom = zext i8 %bits to i64 | |||||
%shr = lshr i64 %a, %sh_prom | |||||
%shl = shl i64 %b, 1 | |||||
%xor0 = xor i8 %bits, 63 | |||||
%xor = zext i8 %xor0 to i64 | |||||
%shl2 = shl i64 %shl, %xor | |||||
%or = or i64 %shl2, %shr | |||||
ret i64 %or | |||||
} | |||||
Most of these tests should probably be in shift-double.ll (tested on 32 and 64bit targets) and just the 2*i64 cases kept here in shift-double-x86_64.ll