364 lines
11 KiB
LLVM
364 lines
11 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X64
|
|
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=CMOV
|
|
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=NOCMOV
|
|
|
|
; PR46809
|
|
|
|
define i32 @sadd_add_imm(i32 %x, i32 %y) {
|
|
; X64-LABEL: sadd_add_imm:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; X64-NEXT: leal (%rdi,%rsi), %eax
|
|
; X64-NEXT: addl $100, %eax
|
|
; X64-NEXT: addl %esi, %edi
|
|
; X64-NEXT: cmovnol %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: sadd_add_imm:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: leal (%eax,%ecx), %edx
|
|
; CMOV-NEXT: addl $100, %edx
|
|
; CMOV-NEXT: addl %ecx, %eax
|
|
; CMOV-NEXT: cmovol %edx, %eax
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: sadd_add_imm:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: leal (%eax,%edx), %ecx
|
|
; NOCMOV-NEXT: addl %edx, %eax
|
|
; NOCMOV-NEXT: jno .LBB0_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: addl $100, %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB0_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%a = add i32 %v2, 100
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @sadd_add_load(i32 %x, i32 %y, i32* %pz) nounwind {
|
|
; X64-LABEL: sadd_add_load:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; X64-NEXT: leal (%rdi,%rsi), %eax
|
|
; X64-NEXT: addl (%rdx), %eax
|
|
; X64-NEXT: addl %esi, %edi
|
|
; X64-NEXT: cmovnol %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: sadd_add_load:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: pushl %esi
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; CMOV-NEXT: leal (%eax,%edx), %esi
|
|
; CMOV-NEXT: addl (%ecx), %esi
|
|
; CMOV-NEXT: addl %edx, %eax
|
|
; CMOV-NEXT: cmovol %esi, %eax
|
|
; CMOV-NEXT: popl %esi
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: sadd_add_load:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: leal (%eax,%edx), %ecx
|
|
; NOCMOV-NEXT: addl %edx, %eax
|
|
; NOCMOV-NEXT: jno .LBB1_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: addl (%eax), %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB1_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%z = load i32, i32* %pz
|
|
%a = add i32 %v2, %z
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @uadd_add_imm(i32 %x, i32 %y) {
|
|
; X64-LABEL: uadd_add_imm:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; X64-NEXT: leal (%rdi,%rsi), %eax
|
|
; X64-NEXT: addl $100, %eax
|
|
; X64-NEXT: addl %esi, %edi
|
|
; X64-NEXT: cmovael %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: uadd_add_imm:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: leal (%eax,%ecx), %edx
|
|
; CMOV-NEXT: addl $100, %edx
|
|
; CMOV-NEXT: addl %ecx, %eax
|
|
; CMOV-NEXT: cmovbl %edx, %eax
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: uadd_add_imm:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: leal (%eax,%edx), %ecx
|
|
; NOCMOV-NEXT: addl %edx, %eax
|
|
; NOCMOV-NEXT: jae .LBB2_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: addl $100, %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB2_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%a = add i32 %v2, 100
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @uadd_add_load(i32 %x, i32 %y, i32* %pz) nounwind {
|
|
; X64-LABEL: uadd_add_load:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; X64-NEXT: leal (%rdi,%rsi), %eax
|
|
; X64-NEXT: addl (%rdx), %eax
|
|
; X64-NEXT: addl %esi, %edi
|
|
; X64-NEXT: cmovael %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: uadd_add_load:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: pushl %esi
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; CMOV-NEXT: leal (%eax,%edx), %esi
|
|
; CMOV-NEXT: addl (%ecx), %esi
|
|
; CMOV-NEXT: addl %edx, %eax
|
|
; CMOV-NEXT: cmovbl %esi, %eax
|
|
; CMOV-NEXT: popl %esi
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: uadd_add_load:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: leal (%eax,%edx), %ecx
|
|
; NOCMOV-NEXT: addl %edx, %eax
|
|
; NOCMOV-NEXT: jae .LBB3_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: addl (%eax), %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB3_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%z = load i32, i32* %pz
|
|
%a = add i32 %v2, %z
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @ssub_add_imm(i32 %x, i32 %y) {
|
|
; X64-LABEL: ssub_add_imm:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: subl %esi, %eax
|
|
; X64-NEXT: addl $100, %eax
|
|
; X64-NEXT: subl %esi, %edi
|
|
; X64-NEXT: cmovnol %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: ssub_add_imm:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: movl %eax, %edx
|
|
; CMOV-NEXT: subl %ecx, %edx
|
|
; CMOV-NEXT: addl $100, %edx
|
|
; CMOV-NEXT: subl %ecx, %eax
|
|
; CMOV-NEXT: cmovol %edx, %eax
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: ssub_add_imm:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: movl %eax, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %eax
|
|
; NOCMOV-NEXT: jno .LBB4_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: addl $100, %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB4_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%a = add i32 %v2, 100
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @ssub_add_load(i32 %x, i32 %y, i32* %pz) nounwind {
|
|
; X64-LABEL: ssub_add_load:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: subl %esi, %eax
|
|
; X64-NEXT: addl (%rdx), %eax
|
|
; X64-NEXT: subl %esi, %edi
|
|
; X64-NEXT: cmovnol %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: ssub_add_load:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: pushl %esi
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; CMOV-NEXT: movl %eax, %esi
|
|
; CMOV-NEXT: subl %edx, %esi
|
|
; CMOV-NEXT: addl (%ecx), %esi
|
|
; CMOV-NEXT: subl %edx, %eax
|
|
; CMOV-NEXT: cmovol %esi, %eax
|
|
; CMOV-NEXT: popl %esi
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: ssub_add_load:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: movl %eax, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %eax
|
|
; NOCMOV-NEXT: jno .LBB5_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: addl (%eax), %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB5_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%z = load i32, i32* %pz
|
|
%a = add i32 %v2, %z
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @usub_add_imm(i32 %x, i32 %y) {
|
|
; X64-LABEL: usub_add_imm:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: subl %esi, %eax
|
|
; X64-NEXT: addl $100, %eax
|
|
; X64-NEXT: subl %esi, %edi
|
|
; X64-NEXT: cmovael %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: usub_add_imm:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: movl %eax, %edx
|
|
; CMOV-NEXT: subl %ecx, %edx
|
|
; CMOV-NEXT: addl $100, %edx
|
|
; CMOV-NEXT: subl %ecx, %eax
|
|
; CMOV-NEXT: cmovbl %edx, %eax
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: usub_add_imm:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: movl %eax, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %eax
|
|
; NOCMOV-NEXT: jae .LBB6_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: addl $100, %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB6_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%a = add i32 %v2, 100
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @usub_add_load(i32 %x, i32 %y, i32* %pz) nounwind {
|
|
; X64-LABEL: usub_add_load:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: subl %esi, %eax
|
|
; X64-NEXT: addl (%rdx), %eax
|
|
; X64-NEXT: subl %esi, %edi
|
|
; X64-NEXT: cmovael %edi, %eax
|
|
; X64-NEXT: retq
|
|
;
|
|
; CMOV-LABEL: usub_add_load:
|
|
; CMOV: # %bb.0:
|
|
; CMOV-NEXT: pushl %esi
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; CMOV-NEXT: movl %eax, %esi
|
|
; CMOV-NEXT: subl %edx, %esi
|
|
; CMOV-NEXT: addl (%ecx), %esi
|
|
; CMOV-NEXT: subl %edx, %eax
|
|
; CMOV-NEXT: cmovbl %esi, %eax
|
|
; CMOV-NEXT: popl %esi
|
|
; CMOV-NEXT: retl
|
|
;
|
|
; NOCMOV-LABEL: usub_add_load:
|
|
; NOCMOV: # %bb.0:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; NOCMOV-NEXT: movl %eax, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %ecx
|
|
; NOCMOV-NEXT: subl %edx, %eax
|
|
; NOCMOV-NEXT: jae .LBB7_2
|
|
; NOCMOV-NEXT: # %bb.1:
|
|
; NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; NOCMOV-NEXT: addl (%eax), %ecx
|
|
; NOCMOV-NEXT: movl %ecx, %eax
|
|
; NOCMOV-NEXT: .LBB7_2:
|
|
; NOCMOV-NEXT: retl
|
|
%o = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
|
|
%v1 = extractvalue { i32, i1 } %o, 1
|
|
%v2 = extractvalue { i32, i1 } %o, 0
|
|
%z = load i32, i32* %pz
|
|
%a = add i32 %v2, %z
|
|
%r = select i1 %v1, i32 %a, i32 %v2
|
|
ret i32 %r
|
|
}
|
|
|
|
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
|
|
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
|
|
declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
|
|
declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
|