llvm-project/llvm/test/CodeGen/X86/sadd_sat_plus.ll
Guozhi Wei 1e46dcb77b [TwoAddressInstructionPass] Put all new instructions into DistanceMap
In function convertInstTo3Addr, after converting a two address instruction into
three address instruction, only the last new instruction is inserted into
DistanceMap. This is wrong, DistanceMap should track all instructions from the
beginning of current MBB to the working instruction. When a two address
instruction is converted to three address instruction, multiple instructions may
be generated (usually an extra COPY is generated), all of them should be
inserted into DistanceMap.

Similarly when unfolding memory operand in function tryInstructionTransform
DistanceMap is not maintained correctly.

Differential Revision: https://reviews.llvm.org/D111857
2021-10-28 11:11:59 -07:00

184 lines
5.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefix=X86
; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64
declare i4 @llvm.sadd.sat.i4(i4, i4)
declare i8 @llvm.sadd.sat.i8(i8, i8)
declare i16 @llvm.sadd.sat.i16(i16, i16)
declare i32 @llvm.sadd.sat.i32(i32, i32)
declare i64 @llvm.sadd.sat.i64(i64, i64)
define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
; X86-LABEL: func32:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: imull {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: leal (%eax,%ecx), %edx
; X86-NEXT: sarl $31, %edx
; X86-NEXT: xorl $-2147483648, %edx # imm = 0x80000000
; X86-NEXT: addl %ecx, %eax
; X86-NEXT: cmovol %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: func32:
; X64: # %bb.0:
; X64-NEXT: # kill: def $esi killed $esi def $rsi
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: imull %edx, %esi
; X64-NEXT: leal (%rdi,%rsi), %eax
; X64-NEXT: sarl $31, %eax
; X64-NEXT: xorl $-2147483648, %eax # imm = 0x80000000
; X64-NEXT: addl %edi, %esi
; X64-NEXT: cmovnol %esi, %eax
; X64-NEXT: retq
%a = mul i32 %y, %z
%tmp = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %a)
ret i32 %tmp
}
define i64 @func64(i64 %x, i64 %y, i64 %z) nounwind {
; X86-LABEL: func64:
; X86: # %bb.0:
; X86-NEXT: pushl %ebx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
; X86-NEXT: adcl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: seto %bl
; X86-NEXT: movl %ecx, %edx
; X86-NEXT: sarl $31, %edx
; X86-NEXT: testb %bl, %bl
; X86-NEXT: cmovnel %edx, %eax
; X86-NEXT: xorl $-2147483648, %edx # imm = 0x80000000
; X86-NEXT: testb %bl, %bl
; X86-NEXT: cmovel %ecx, %edx
; X86-NEXT: popl %ebx
; X86-NEXT: retl
;
; X64-LABEL: func64:
; X64: # %bb.0:
; X64-NEXT: leaq (%rdi,%rdx), %rcx
; X64-NEXT: sarq $63, %rcx
; X64-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
; X64-NEXT: xorq %rcx, %rax
; X64-NEXT: addq %rdx, %rdi
; X64-NEXT: cmovnoq %rdi, %rax
; X64-NEXT: retq
%a = mul i64 %y, %z
%tmp = call i64 @llvm.sadd.sat.i64(i64 %x, i64 %z)
ret i64 %tmp
}
define signext i16 @func16(i16 signext %x, i16 signext %y, i16 signext %z) nounwind {
; X86-LABEL: func16:
; X86: # %bb.0:
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
; X86-NEXT: imulw {{[0-9]+}}(%esp), %ax
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl %eax, %edx
; X86-NEXT: addw %cx, %dx
; X86-NEXT: movswl %dx, %edx
; X86-NEXT: sarl $15, %edx
; X86-NEXT: xorl $-32768, %edx # imm = 0x8000
; X86-NEXT: addw %cx, %ax
; X86-NEXT: cmovol %edx, %eax
; X86-NEXT: # kill: def $ax killed $ax killed $eax
; X86-NEXT: retl
;
; X64-LABEL: func16:
; X64: # %bb.0:
; X64-NEXT: # kill: def $esi killed $esi def $rsi
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: imull %edx, %esi
; X64-NEXT: leal (%rdi,%rsi), %eax
; X64-NEXT: cwtl
; X64-NEXT: sarl $15, %eax
; X64-NEXT: xorl $-32768, %eax # imm = 0x8000
; X64-NEXT: addw %si, %di
; X64-NEXT: cmovnol %edi, %eax
; X64-NEXT: # kill: def $ax killed $ax killed $eax
; X64-NEXT: retq
%a = mul i16 %y, %z
%tmp = call i16 @llvm.sadd.sat.i16(i16 %x, i16 %a)
ret i16 %tmp
}
define signext i8 @func8(i8 signext %x, i8 signext %y, i8 signext %z) nounwind {
; X86-LABEL: func8:
; X86: # %bb.0:
; X86-NEXT: movb {{[0-9]+}}(%esp), %al
; X86-NEXT: mulb {{[0-9]+}}(%esp)
; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
; X86-NEXT: movl %eax, %edx
; X86-NEXT: addb %cl, %dl
; X86-NEXT: sarb $7, %dl
; X86-NEXT: xorb $-128, %dl
; X86-NEXT: addb %cl, %al
; X86-NEXT: movzbl %al, %ecx
; X86-NEXT: movzbl %dl, %eax
; X86-NEXT: cmovnol %ecx, %eax
; X86-NEXT: # kill: def $al killed $al killed $eax
; X86-NEXT: retl
;
; X64-LABEL: func8:
; X64: # %bb.0:
; X64-NEXT: movl %esi, %eax
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: # kill: def $al killed $al killed $eax
; X64-NEXT: mulb %dl
; X64-NEXT: # kill: def $al killed $al def $rax
; X64-NEXT: leal (%rdi,%rax), %ecx
; X64-NEXT: sarb $7, %cl
; X64-NEXT: xorb $-128, %cl
; X64-NEXT: addb %al, %dil
; X64-NEXT: movzbl %dil, %edx
; X64-NEXT: movzbl %cl, %eax
; X64-NEXT: cmovnol %edx, %eax
; X64-NEXT: # kill: def $al killed $al killed $eax
; X64-NEXT: retq
%a = mul i8 %y, %z
%tmp = call i8 @llvm.sadd.sat.i8(i8 %x, i8 %a)
ret i8 %tmp
}
define signext i4 @func4(i4 signext %x, i4 signext %y, i4 signext %z) nounwind {
; X86-LABEL: func4:
; X86: # %bb.0:
; X86-NEXT: movb {{[0-9]+}}(%esp), %al
; X86-NEXT: mulb {{[0-9]+}}(%esp)
; X86-NEXT: shlb $4, %al
; X86-NEXT: sarb $4, %al
; X86-NEXT: addb {{[0-9]+}}(%esp), %al
; X86-NEXT: movzbl %al, %ecx
; X86-NEXT: cmpb $7, %al
; X86-NEXT: movl $7, %eax
; X86-NEXT: cmovll %ecx, %eax
; X86-NEXT: cmpb $-7, %al
; X86-NEXT: movl $248, %ecx
; X86-NEXT: cmovgel %eax, %ecx
; X86-NEXT: movsbl %cl, %eax
; X86-NEXT: retl
;
; X64-LABEL: func4:
; X64: # %bb.0:
; X64-NEXT: movl %esi, %eax
; X64-NEXT: # kill: def $al killed $al killed $eax
; X64-NEXT: mulb %dl
; X64-NEXT: shlb $4, %al
; X64-NEXT: sarb $4, %al
; X64-NEXT: addb %dil, %al
; X64-NEXT: movzbl %al, %eax
; X64-NEXT: cmpb $7, %al
; X64-NEXT: movl $7, %ecx
; X64-NEXT: cmovll %eax, %ecx
; X64-NEXT: cmpb $-7, %cl
; X64-NEXT: movl $248, %eax
; X64-NEXT: cmovgel %ecx, %eax
; X64-NEXT: movsbl %al, %eax
; X64-NEXT: retq
%a = mul i4 %y, %z
%tmp = call i4 @llvm.sadd.sat.i4(i4 %x, i4 %a)
ret i4 %tmp
}