Files
clang-p2996/llvm/test/CodeGen/X86/fast-isel-shift.ll
Shengchen Kan 77589e945f [X86] Remove patterns for shift/rotate with immediate 1 and optimize during MC lowering
It's first suggested by @craig.topper  in D150068. I think there are at least three pros

1. This can reduce the patterns during ISEL, as a result, reducing the bytes in X86GenDAGISel.inc
2. The patterns for shift/rotate with immediate 1 look quite similar to shift/rotate with immediate 8. So this can be seen as eliminating "duplicate" code.
3. Delay the optimization from imm8 to imm1, so that the previous optimization passes do not need to handle the version of imm1

It improves fast isel code and makes X86DomainReassignment work for shifts by 1, but regressed global isel, though no one should care.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D150107
2023-05-17 19:55:44 +08:00

420 lines
10 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 | FileCheck %s
define i8 @shl_i8(i8 %a, i8 %b) {
; CHECK-LABEL: shl_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shlb %cl, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = shl i8 %a, %b
ret i8 %c
}
define i16 @shl_i16(i16 %a, i16 %b) {
; CHECK-LABEL: shl_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cx killed $cx killed $ecx
; CHECK-NEXT: ## kill: def $cl killed $cx
; CHECK-NEXT: shlw %cl, %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = shl i16 %a, %b
ret i16 %c
}
define i32 @shl_i32(i32 %a, i32 %b) {
; CHECK-LABEL: shl_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
; CHECK-NEXT: retq
%c = shl i32 %a, %b
ret i32 %c
}
define i64 @shl_i64(i64 %a, i64 %b) {
; CHECK-LABEL: shl_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: ## kill: def $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
%c = shl i64 %a, %b
ret i64 %c
}
define i8 @lshr_i8(i8 %a, i8 %b) {
; CHECK-LABEL: lshr_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shrb %cl, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = lshr i8 %a, %b
ret i8 %c
}
define i16 @lshr_i16(i16 %a, i16 %b) {
; CHECK-LABEL: lshr_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cx killed $cx killed $ecx
; CHECK-NEXT: ## kill: def $cl killed $cx
; CHECK-NEXT: shrw %cl, %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = lshr i16 %a, %b
ret i16 %c
}
define i32 @lshr_i32(i32 %a, i32 %b) {
; CHECK-LABEL: lshr_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cl killed $ecx
; CHECK-NEXT: shrl %cl, %eax
; CHECK-NEXT: retq
%c = lshr i32 %a, %b
ret i32 %c
}
define i64 @lshr_i64(i64 %a, i64 %b) {
; CHECK-LABEL: lshr_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: ## kill: def $cl killed $rcx
; CHECK-NEXT: shrq %cl, %rax
; CHECK-NEXT: retq
%c = lshr i64 %a, %b
ret i64 %c
}
define i8 @ashr_i8(i8 %a, i8 %b) {
; CHECK-LABEL: ashr_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: sarb %cl, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = ashr i8 %a, %b
ret i8 %c
}
define i16 @ashr_i16(i16 %a, i16 %b) {
; CHECK-LABEL: ashr_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cx killed $cx killed $ecx
; CHECK-NEXT: ## kill: def $cl killed $cx
; CHECK-NEXT: sarw %cl, %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = ashr i16 %a, %b
ret i16 %c
}
define i32 @ashr_i32(i32 %a, i32 %b) {
; CHECK-LABEL: ashr_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: ## kill: def $cl killed $ecx
; CHECK-NEXT: sarl %cl, %eax
; CHECK-NEXT: retq
%c = ashr i32 %a, %b
ret i32 %c
}
define i64 @ashr_i64(i64 %a, i64 %b) {
; CHECK-LABEL: ashr_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: ## kill: def $cl killed $rcx
; CHECK-NEXT: sarq %cl, %rax
; CHECK-NEXT: retq
%c = ashr i64 %a, %b
ret i64 %c
}
define i8 @shl_imm1_i8(i8 %a) {
; CHECK-LABEL: shl_imm1_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: ## kill: def $edi killed $edi def $rdi
; CHECK-NEXT: leal (,%rdi,2), %eax
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = shl i8 %a, 1
ret i8 %c
}
define i16 @shl_imm1_i16(i16 %a) {
; CHECK-LABEL: shl_imm1_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: ## kill: def $edi killed $edi def $rdi
; CHECK-NEXT: leal (,%rdi,2), %eax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = shl i16 %a, 1
ret i16 %c
}
define i32 @shl_imm1_i32(i32 %a) {
; CHECK-LABEL: shl_imm1_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: ## kill: def $edi killed $edi def $rdi
; CHECK-NEXT: leal (,%rdi,2), %eax
; CHECK-NEXT: retq
%c = shl i32 %a, 1
ret i32 %c
}
define i64 @shl_imm1_i64(i64 %a) {
; CHECK-LABEL: shl_imm1_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: leaq (,%rdi,2), %rax
; CHECK-NEXT: retq
%c = shl i64 %a, 1
ret i64 %c
}
define i8 @lshr_imm1_i8(i8 %a) {
; CHECK-LABEL: lshr_imm1_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shrb %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = lshr i8 %a, 1
ret i8 %c
}
define i16 @lshr_imm1_i16(i16 %a) {
; CHECK-LABEL: lshr_imm1_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shrw %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = lshr i16 %a, 1
ret i16 %c
}
define i32 @lshr_imm1_i32(i32 %a) {
; CHECK-LABEL: lshr_imm1_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shrl %eax
; CHECK-NEXT: retq
%c = lshr i32 %a, 1
ret i32 %c
}
define i64 @lshr_imm1_i64(i64 %a) {
; CHECK-LABEL: lshr_imm1_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: shrq %rax
; CHECK-NEXT: retq
%c = lshr i64 %a, 1
ret i64 %c
}
define i8 @ashr_imm1_i8(i8 %a) {
; CHECK-LABEL: ashr_imm1_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: sarb %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = ashr i8 %a, 1
ret i8 %c
}
define i16 @ashr_imm1_i16(i16 %a) {
; CHECK-LABEL: ashr_imm1_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: sarw %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = ashr i16 %a, 1
ret i16 %c
}
define i32 @ashr_imm1_i32(i32 %a) {
; CHECK-LABEL: ashr_imm1_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: sarl %eax
; CHECK-NEXT: retq
%c = ashr i32 %a, 1
ret i32 %c
}
define i64 @ashr_imm1_i64(i64 %a) {
; CHECK-LABEL: ashr_imm1_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: sarq %rax
; CHECK-NEXT: retq
%c = ashr i64 %a, 1
ret i64 %c
}
define i8 @shl_imm4_i8(i8 %a) {
; CHECK-LABEL: shl_imm4_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shlb $4, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = shl i8 %a, 4
ret i8 %c
}
define i16 @shl_imm4_i16(i16 %a) {
; CHECK-LABEL: shl_imm4_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shlw $4, %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = shl i16 %a, 4
ret i16 %c
}
define i32 @shl_imm4_i32(i32 %a) {
; CHECK-LABEL: shl_imm4_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shll $4, %eax
; CHECK-NEXT: retq
%c = shl i32 %a, 4
ret i32 %c
}
define i64 @shl_imm4_i64(i64 %a) {
; CHECK-LABEL: shl_imm4_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: shlq $4, %rax
; CHECK-NEXT: retq
%c = shl i64 %a, 4
ret i64 %c
}
define i8 @lshr_imm4_i8(i8 %a) {
; CHECK-LABEL: lshr_imm4_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shrb $4, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = lshr i8 %a, 4
ret i8 %c
}
define i16 @lshr_imm4_i16(i16 %a) {
; CHECK-LABEL: lshr_imm4_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shrw $4, %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = lshr i16 %a, 4
ret i16 %c
}
define i32 @lshr_imm4_i32(i32 %a) {
; CHECK-LABEL: lshr_imm4_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: shrl $4, %eax
; CHECK-NEXT: retq
%c = lshr i32 %a, 4
ret i32 %c
}
define i64 @lshr_imm4_i64(i64 %a) {
; CHECK-LABEL: lshr_imm4_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: shrq $4, %rax
; CHECK-NEXT: retq
%c = lshr i64 %a, 4
ret i64 %c
}
define i8 @ashr_imm4_i8(i8 %a) {
; CHECK-LABEL: ashr_imm4_i8:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: sarb $4, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%c = ashr i8 %a, 4
ret i8 %c
}
define i16 @ashr_imm4_i16(i16 %a) {
; CHECK-LABEL: ashr_imm4_i16:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: sarw $4, %ax
; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%c = ashr i16 %a, 4
ret i16 %c
}
define i32 @ashr_imm4_i32(i32 %a) {
; CHECK-LABEL: ashr_imm4_i32:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: sarl $4, %eax
; CHECK-NEXT: retq
%c = ashr i32 %a, 4
ret i32 %c
}
define i64 @ashr_imm4_i64(i64 %a) {
; CHECK-LABEL: ashr_imm4_i64:
; CHECK: ## %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: sarq $4, %rax
; CHECK-NEXT: retq
%c = ashr i64 %a, 4
ret i64 %c
}
; Make sure we don't crash on out of bounds i8 shifts.
define i8 @PR36731(i8 %a) {
; CHECK-LABEL: PR36731:
; CHECK: ## %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: movb $255, %cl
; CHECK-NEXT: shlb %cl, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%b = shl i8 %a, -1
ret i8 %b
}