497 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			497 lines
		
	
	
		
			15 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 $edi killed $edi def $rdi
 | |
| ; X64-NEXT:    addl %esi, %edi
 | |
| ; X64-NEXT:    leal 100(%rdi), %eax
 | |
| ; X64-NEXT:    cmovnol %edi, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: sadd_add_imm:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    leal 100(%ecx), %eax
 | |
| ; CMOV-NEXT:    cmovnol %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: sadd_add_imm:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    addl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    jno .LBB0_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    addl $100, %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 $edi killed $edi def $rdi
 | |
| ; X64-NEXT:    addl %esi, %edi
 | |
| ; X64-NEXT:    leal 100(%rdi), %eax
 | |
| ; X64-NEXT:    cmovael %edi, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: uadd_add_imm:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    leal 100(%ecx), %eax
 | |
| ; CMOV-NEXT:    cmovael %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: uadd_add_imm:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    addl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    jae .LBB2_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    addl $100, %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:    # kill: def $edi killed $edi def $rdi
 | |
| ; X64-NEXT:    subl %esi, %edi
 | |
| ; X64-NEXT:    leal 100(%rdi), %eax
 | |
| ; X64-NEXT:    cmovnol %edi, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: ssub_add_imm:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    leal 100(%ecx), %eax
 | |
| ; CMOV-NEXT:    cmovnol %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: ssub_add_imm:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    subl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    jno .LBB4_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    addl $100, %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:    # kill: def $edi killed $edi def $rdi
 | |
| ; X64-NEXT:    subl %esi, %edi
 | |
| ; X64-NEXT:    leal 100(%rdi), %eax
 | |
| ; X64-NEXT:    cmovael %edi, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: usub_add_imm:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    leal 100(%ecx), %eax
 | |
| ; CMOV-NEXT:    cmovael %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: usub_add_imm:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    subl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    jae .LBB6_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    addl $100, %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
 | |
| }
 | |
| 
 | |
| define i32 @smul_add_imm(i32 %x, i32 %y) {
 | |
| ; X64-LABEL: smul_add_imm:
 | |
| ; X64:       # %bb.0:
 | |
| ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 | |
| ; X64-NEXT:    imull %esi, %edi
 | |
| ; X64-NEXT:    leal 100(%rdi), %eax
 | |
| ; X64-NEXT:    cmovnol %edi, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: smul_add_imm:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    imull {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    leal 100(%ecx), %eax
 | |
| ; CMOV-NEXT:    cmovnol %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: smul_add_imm:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    imull {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    jno .LBB8_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    addl $100, %eax
 | |
| ; NOCMOV-NEXT:  .LBB8_2:
 | |
| ; NOCMOV-NEXT:    retl
 | |
|   %o = tail call { i32, i1 } @llvm.smul.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 @smul_add_load(i32 %x, i32 %y, i32* %pz) nounwind {
 | |
| ; X64-LABEL: smul_add_load:
 | |
| ; X64:       # %bb.0:
 | |
| ; X64-NEXT:    movl %edi, %eax
 | |
| ; X64-NEXT:    imull %esi, %eax
 | |
| ; X64-NEXT:    addl (%rdx), %eax
 | |
| ; X64-NEXT:    imull %esi, %edi
 | |
| ; X64-NEXT:    cmovnol %edi, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: smul_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:    imull %edx, %esi
 | |
| ; CMOV-NEXT:    addl (%ecx), %esi
 | |
| ; CMOV-NEXT:    imull %edx, %eax
 | |
| ; CMOV-NEXT:    cmovol %esi, %eax
 | |
| ; CMOV-NEXT:    popl %esi
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: smul_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:    imull %edx, %ecx
 | |
| ; NOCMOV-NEXT:    imull %edx, %eax
 | |
| ; NOCMOV-NEXT:    jno .LBB9_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    addl (%eax), %ecx
 | |
| ; NOCMOV-NEXT:    movl %ecx, %eax
 | |
| ; NOCMOV-NEXT:  .LBB9_2:
 | |
| ; NOCMOV-NEXT:    retl
 | |
|   %o = tail call { i32, i1 } @llvm.smul.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 @umul_add_imm(i32 %x, i32 %y) {
 | |
| ; X64-LABEL: umul_add_imm:
 | |
| ; X64:       # %bb.0:
 | |
| ; X64-NEXT:    movl %edi, %eax
 | |
| ; X64-NEXT:    mull %esi
 | |
| ; X64-NEXT:    # kill: def $eax killed $eax def $rax
 | |
| ; X64-NEXT:    leal 100(%rax), %ecx
 | |
| ; X64-NEXT:    cmovol %ecx, %eax
 | |
| ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: umul_add_imm:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; CMOV-NEXT:    mull {{[0-9]+}}(%esp)
 | |
| ; CMOV-NEXT:    leal 100(%eax), %ecx
 | |
| ; CMOV-NEXT:    cmovol %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: umul_add_imm:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    mull {{[0-9]+}}(%esp)
 | |
| ; NOCMOV-NEXT:    jno .LBB10_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    addl $100, %eax
 | |
| ; NOCMOV-NEXT:  .LBB10_2:
 | |
| ; NOCMOV-NEXT:    retl
 | |
|   %o = tail call { i32, i1 } @llvm.umul.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 @umul_add_load(i32 %x, i32 %y, i32* %pz) nounwind {
 | |
| ; X64-LABEL: umul_add_load:
 | |
| ; X64:       # %bb.0:
 | |
| ; X64-NEXT:    movq %rdx, %rcx
 | |
| ; X64-NEXT:    movl %edi, %eax
 | |
| ; X64-NEXT:    mull %esi
 | |
| ; X64-NEXT:    seto %dl
 | |
| ; X64-NEXT:    movl (%rcx), %ecx
 | |
| ; X64-NEXT:    addl %eax, %ecx
 | |
| ; X64-NEXT:    testb %dl, %dl
 | |
| ; X64-NEXT:    cmovnel %ecx, %eax
 | |
| ; X64-NEXT:    retq
 | |
| ;
 | |
| ; CMOV-LABEL: umul_add_load:
 | |
| ; CMOV:       # %bb.0:
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; CMOV-NEXT:    mull {{[0-9]+}}(%esp)
 | |
| ; CMOV-NEXT:    seto %dl
 | |
| ; CMOV-NEXT:    movl (%ecx), %ecx
 | |
| ; CMOV-NEXT:    addl %eax, %ecx
 | |
| ; CMOV-NEXT:    testb %dl, %dl
 | |
| ; CMOV-NEXT:    cmovnel %ecx, %eax
 | |
| ; CMOV-NEXT:    retl
 | |
| ;
 | |
| ; NOCMOV-LABEL: umul_add_load:
 | |
| ; NOCMOV:       # %bb.0:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | |
| ; NOCMOV-NEXT:    mull {{[0-9]+}}(%esp)
 | |
| ; NOCMOV-NEXT:    jno .LBB11_2
 | |
| ; NOCMOV-NEXT:  # %bb.1:
 | |
| ; NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | |
| ; NOCMOV-NEXT:    addl (%ecx), %eax
 | |
| ; NOCMOV-NEXT:  .LBB11_2:
 | |
| ; NOCMOV-NEXT:    retl
 | |
|   %o = tail call { i32, i1 } @llvm.umul.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)
 | |
| declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
 | |
| declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
 |