llvm-6502/test/CodeGen/X86/legalize-shift-64.ll
Benjamin Kramer 3bf15ced2b LegalizeIntegerTypes: Reenable the large shift with small amount optimization.
To avoid problems with zero shifts when getting the bits that move between words
we use a trick: first shift the by amount-1, then do another shift by one. When
amount is 0 (and size 32) we first shift by 31, then by one, instead of by 32.

Also fix a latent bug that emitted the low and high words in the wrong order
when shifting right.

Fixes PR12113.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151637 91177308-0d34-0410-b5e6-96231b3b80d8
2012-02-28 17:58:00 +00:00

57 lines
1.2 KiB
LLVM

; RUN: llc -march=x86 < %s | FileCheck %s
define i64 @test1(i32 %xx, i32 %test) nounwind {
%conv = zext i32 %xx to i64
%and = and i32 %test, 7
%sh_prom = zext i32 %and to i64
%shl = shl i64 %conv, %sh_prom
ret i64 %shl
; CHECK: test1:
; CHECK: shll %cl, %eax
; CHECK: xorb $31
; CHECK: shrl %cl, %edx
; CHECK: shrl %edx
}
define i64 @test2(i64 %xx, i32 %test) nounwind {
%and = and i32 %test, 7
%sh_prom = zext i32 %and to i64
%shl = shl i64 %xx, %sh_prom
ret i64 %shl
; CHECK: test2:
; CHECK: shll %cl, %esi
; CHECK: xorb $31
; CHECK: shrl %cl, %edx
; CHECK: shrl %edx
; CHECK: orl %esi, %edx
; CHECK: shll %cl, %eax
}
define i64 @test3(i64 %xx, i32 %test) nounwind {
%and = and i32 %test, 7
%sh_prom = zext i32 %and to i64
%shr = lshr i64 %xx, %sh_prom
ret i64 %shr
; CHECK: test3:
; CHECK: shrl %cl, %esi
; CHECK: xorb $31, %cl
; CHECK: shll %cl, %eax
; CHECK: addl %eax, %eax
; CHECK: orl %esi, %eax
; CHECK: shrl %cl, %edx
}
define i64 @test4(i64 %xx, i32 %test) nounwind {
%and = and i32 %test, 7
%sh_prom = zext i32 %and to i64
%shr = ashr i64 %xx, %sh_prom
ret i64 %shr
; CHECK: test4:
; CHECK: shrl %cl, %esi
; CHECK: xorb $31, %cl
; CHECK: shll %cl, %eax
; CHECK: addl %eax, %eax
; CHECK: orl %esi, %eax
; CHECK: sarl %cl, %edx
}