462 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			462 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 | |
| ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=ENABLED
 | |
| ; RUN: llc --disable-x86-lea-opt < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=DISABLED
 | |
| 
 | |
| %struct.anon1 = type { i32, i32, i32 }
 | |
| %struct.anon2 = type { i32, [32 x i32], i32 }
 | |
| 
 | |
| @arr1 = external global [65 x %struct.anon1], align 16
 | |
| @arr2 = external global [65 x %struct.anon2], align 16
 | |
| 
 | |
| define void @test1(i64 %x) nounwind {
 | |
| ; ENABLED-LABEL: test1:
 | |
| ; ENABLED:       # %bb.0: # %entry
 | |
| ; ENABLED-NEXT:    shlq $2, %rdi
 | |
| ; ENABLED-NEXT:    movl arr1(%rdi,%rdi,2), %ecx
 | |
| ; ENABLED-NEXT:    leaq arr1+4(%rdi,%rdi,2), %rax
 | |
| ; ENABLED-NEXT:    subl arr1+4(%rdi,%rdi,2), %ecx
 | |
| ; ENABLED-NEXT:    addl arr1+8(%rdi,%rdi,2), %ecx
 | |
| ; ENABLED-NEXT:    cmpl $2, %ecx
 | |
| ; ENABLED-NEXT:    je .LBB0_3
 | |
| ; ENABLED-NEXT:  # %bb.1: # %entry
 | |
| ; ENABLED-NEXT:    cmpl $1, %ecx
 | |
| ; ENABLED-NEXT:    jne .LBB0_4
 | |
| ; ENABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; ENABLED-NEXT:    movl $111, (%rax)
 | |
| ; ENABLED-NEXT:    movl $222, 4(%rax)
 | |
| ; ENABLED-NEXT:    retq
 | |
| ; ENABLED-NEXT:  .LBB0_3: # %sw.bb.2
 | |
| ; ENABLED-NEXT:    movl $333, (%rax) # imm = 0x14D
 | |
| ; ENABLED-NEXT:    movl $444, 4(%rax) # imm = 0x1BC
 | |
| ; ENABLED-NEXT:  .LBB0_4: # %sw.epilog
 | |
| ; ENABLED-NEXT:    retq
 | |
| ;
 | |
| ; DISABLED-LABEL: test1:
 | |
| ; DISABLED:       # %bb.0: # %entry
 | |
| ; DISABLED-NEXT:    shlq $2, %rdi
 | |
| ; DISABLED-NEXT:    movl arr1(%rdi,%rdi,2), %edx
 | |
| ; DISABLED-NEXT:    leaq arr1+4(%rdi,%rdi,2), %rax
 | |
| ; DISABLED-NEXT:    subl arr1+4(%rdi,%rdi,2), %edx
 | |
| ; DISABLED-NEXT:    leaq arr1+8(%rdi,%rdi,2), %rcx
 | |
| ; DISABLED-NEXT:    addl arr1+8(%rdi,%rdi,2), %edx
 | |
| ; DISABLED-NEXT:    cmpl $2, %edx
 | |
| ; DISABLED-NEXT:    je .LBB0_3
 | |
| ; DISABLED-NEXT:  # %bb.1: # %entry
 | |
| ; DISABLED-NEXT:    cmpl $1, %edx
 | |
| ; DISABLED-NEXT:    jne .LBB0_4
 | |
| ; DISABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; DISABLED-NEXT:    movl $111, (%rax)
 | |
| ; DISABLED-NEXT:    movl $222, (%rcx)
 | |
| ; DISABLED-NEXT:    retq
 | |
| ; DISABLED-NEXT:  .LBB0_3: # %sw.bb.2
 | |
| ; DISABLED-NEXT:    movl $333, (%rax) # imm = 0x14D
 | |
| ; DISABLED-NEXT:    movl $444, (%rcx) # imm = 0x1BC
 | |
| ; DISABLED-NEXT:  .LBB0_4: # %sw.epilog
 | |
| ; DISABLED-NEXT:    retq
 | |
| entry:
 | |
|   %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
 | |
|   %tmp = load i32, i32* %a, align 4
 | |
|   %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
 | |
|   %tmp1 = load i32, i32* %b, align 4
 | |
|   %sub = sub i32 %tmp, %tmp1
 | |
|   %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
 | |
|   %tmp2 = load i32, i32* %c, align 4
 | |
|   %add = add nsw i32 %sub, %tmp2
 | |
|   switch i32 %add, label %sw.epilog [
 | |
|     i32 1, label %sw.bb.1
 | |
|     i32 2, label %sw.bb.2
 | |
|   ]
 | |
| 
 | |
| sw.bb.1:                                          ; preds = %entry
 | |
|   store i32 111, i32* %b, align 4
 | |
|   store i32 222, i32* %c, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.bb.2:                                          ; preds = %entry
 | |
|   store i32 333, i32* %b, align 4
 | |
|   store i32 444, i32* %c, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @test2(i64 %x) nounwind optsize {
 | |
| ; ENABLED-LABEL: test2:
 | |
| ; ENABLED:       # %bb.0: # %entry
 | |
| ; ENABLED-NEXT:    shlq $2, %rdi
 | |
| ; ENABLED-NEXT:    leaq arr1+4(%rdi,%rdi,2), %rax
 | |
| ; ENABLED-NEXT:    movl -4(%rax), %ecx
 | |
| ; ENABLED-NEXT:    subl (%rax), %ecx
 | |
| ; ENABLED-NEXT:    addl 4(%rax), %ecx
 | |
| ; ENABLED-NEXT:    cmpl $2, %ecx
 | |
| ; ENABLED-NEXT:    je .LBB1_3
 | |
| ; ENABLED-NEXT:  # %bb.1: # %entry
 | |
| ; ENABLED-NEXT:    cmpl $1, %ecx
 | |
| ; ENABLED-NEXT:    jne .LBB1_4
 | |
| ; ENABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; ENABLED-NEXT:    movl $111, (%rax)
 | |
| ; ENABLED-NEXT:    movl $222, 4(%rax)
 | |
| ; ENABLED-NEXT:    retq
 | |
| ; ENABLED-NEXT:  .LBB1_3: # %sw.bb.2
 | |
| ; ENABLED-NEXT:    movl $333, (%rax) # imm = 0x14D
 | |
| ; ENABLED-NEXT:    movl $444, 4(%rax) # imm = 0x1BC
 | |
| ; ENABLED-NEXT:  .LBB1_4: # %sw.epilog
 | |
| ; ENABLED-NEXT:    retq
 | |
| ;
 | |
| ; DISABLED-LABEL: test2:
 | |
| ; DISABLED:       # %bb.0: # %entry
 | |
| ; DISABLED-NEXT:    shlq $2, %rdi
 | |
| ; DISABLED-NEXT:    movl arr1(%rdi,%rdi,2), %edx
 | |
| ; DISABLED-NEXT:    leaq arr1+4(%rdi,%rdi,2), %rax
 | |
| ; DISABLED-NEXT:    subl arr1+4(%rdi,%rdi,2), %edx
 | |
| ; DISABLED-NEXT:    leaq arr1+8(%rdi,%rdi,2), %rcx
 | |
| ; DISABLED-NEXT:    addl arr1+8(%rdi,%rdi,2), %edx
 | |
| ; DISABLED-NEXT:    cmpl $2, %edx
 | |
| ; DISABLED-NEXT:    je .LBB1_3
 | |
| ; DISABLED-NEXT:  # %bb.1: # %entry
 | |
| ; DISABLED-NEXT:    cmpl $1, %edx
 | |
| ; DISABLED-NEXT:    jne .LBB1_4
 | |
| ; DISABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; DISABLED-NEXT:    movl $111, (%rax)
 | |
| ; DISABLED-NEXT:    movl $222, (%rcx)
 | |
| ; DISABLED-NEXT:    retq
 | |
| ; DISABLED-NEXT:  .LBB1_3: # %sw.bb.2
 | |
| ; DISABLED-NEXT:    movl $333, (%rax) # imm = 0x14D
 | |
| ; DISABLED-NEXT:    movl $444, (%rcx) # imm = 0x1BC
 | |
| ; DISABLED-NEXT:  .LBB1_4: # %sw.epilog
 | |
| ; DISABLED-NEXT:    retq
 | |
| entry:
 | |
|   %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
 | |
|   %tmp = load i32, i32* %a, align 4
 | |
|   %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
 | |
|   %tmp1 = load i32, i32* %b, align 4
 | |
|   %sub = sub i32 %tmp, %tmp1
 | |
|   %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
 | |
|   %tmp2 = load i32, i32* %c, align 4
 | |
|   %add = add nsw i32 %sub, %tmp2
 | |
|   switch i32 %add, label %sw.epilog [
 | |
|     i32 1, label %sw.bb.1
 | |
|     i32 2, label %sw.bb.2
 | |
|   ]
 | |
| 
 | |
| sw.bb.1:                                          ; preds = %entry
 | |
|   store i32 111, i32* %b, align 4
 | |
|   store i32 222, i32* %c, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.bb.2:                                          ; preds = %entry
 | |
|   store i32 333, i32* %b, align 4
 | |
|   store i32 444, i32* %c, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| ; Check that LEA optimization pass takes into account a resultant address
 | |
| ; displacement when choosing a LEA instruction for replacing a redundant
 | |
| ; address recalculation.
 | |
| 
 | |
| define void @test3(i64 %x) nounwind optsize {
 | |
| ; ENABLED-LABEL: test3:
 | |
| ; ENABLED:       # %bb.0: # %entry
 | |
| ; ENABLED-NEXT:    movq %rdi, %rax
 | |
| ; ENABLED-NEXT:    shlq $7, %rax
 | |
| ; ENABLED-NEXT:    leaq arr2+132(%rax,%rdi,8), %rcx
 | |
| ; ENABLED-NEXT:    leaq arr2(%rax,%rdi,8), %rax
 | |
| ; ENABLED-NEXT:    movl (%rcx), %edx
 | |
| ; ENABLED-NEXT:    addl (%rax), %edx
 | |
| ; ENABLED-NEXT:    cmpl $2, %edx
 | |
| ; ENABLED-NEXT:    je .LBB2_3
 | |
| ; ENABLED-NEXT:  # %bb.1: # %entry
 | |
| ; ENABLED-NEXT:    cmpl $1, %edx
 | |
| ; ENABLED-NEXT:    jne .LBB2_4
 | |
| ; ENABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; ENABLED-NEXT:    movl $111, (%rcx)
 | |
| ; ENABLED-NEXT:    movl $222, (%rax)
 | |
| ; ENABLED-NEXT:    retq
 | |
| ; ENABLED-NEXT:  .LBB2_3: # %sw.bb.2
 | |
| ; ENABLED-NEXT:    movl $333, (%rcx) # imm = 0x14D
 | |
| ; ENABLED-NEXT:    movl %eax, (%rax)
 | |
| ; ENABLED-NEXT:  .LBB2_4: # %sw.epilog
 | |
| ; ENABLED-NEXT:    retq
 | |
| ;
 | |
| ; DISABLED-LABEL: test3:
 | |
| ; DISABLED:       # %bb.0: # %entry
 | |
| ; DISABLED-NEXT:    movq %rdi, %rsi
 | |
| ; DISABLED-NEXT:    shlq $7, %rsi
 | |
| ; DISABLED-NEXT:    leaq arr2+132(%rsi,%rdi,8), %rcx
 | |
| ; DISABLED-NEXT:    leaq arr2(%rsi,%rdi,8), %rax
 | |
| ; DISABLED-NEXT:    movl arr2+132(%rsi,%rdi,8), %edx
 | |
| ; DISABLED-NEXT:    addl arr2(%rsi,%rdi,8), %edx
 | |
| ; DISABLED-NEXT:    cmpl $2, %edx
 | |
| ; DISABLED-NEXT:    je .LBB2_3
 | |
| ; DISABLED-NEXT:  # %bb.1: # %entry
 | |
| ; DISABLED-NEXT:    cmpl $1, %edx
 | |
| ; DISABLED-NEXT:    jne .LBB2_4
 | |
| ; DISABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; DISABLED-NEXT:    movl $111, (%rcx)
 | |
| ; DISABLED-NEXT:    movl $222, (%rax)
 | |
| ; DISABLED-NEXT:    retq
 | |
| ; DISABLED-NEXT:  .LBB2_3: # %sw.bb.2
 | |
| ; DISABLED-NEXT:    movl $333, (%rcx) # imm = 0x14D
 | |
| ; DISABLED-NEXT:    movl %eax, (%rax)
 | |
| ; DISABLED-NEXT:  .LBB2_4: # %sw.epilog
 | |
| ; DISABLED-NEXT:    retq
 | |
| entry:
 | |
|   %a = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 2
 | |
|   %tmp = load i32, i32* %a, align 4
 | |
|   %b = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 0
 | |
|   %tmp1 = load i32, i32* %b, align 4
 | |
|   %add = add nsw i32 %tmp, %tmp1
 | |
|   switch i32 %add, label %sw.epilog [
 | |
|     i32 1, label %sw.bb.1
 | |
|     i32 2, label %sw.bb.2
 | |
|   ]
 | |
| 
 | |
| sw.bb.1:                                          ; preds = %entry
 | |
|   store i32 111, i32* %a, align 4
 | |
|   store i32 222, i32* %b, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.bb.2:                                          ; preds = %entry
 | |
|   store i32 333, i32* %a, align 4
 | |
|   ; Make sure the REG3's definition LEA won't be removed as redundant.
 | |
|   %cvt = ptrtoint i32* %b to i32
 | |
|   store i32 %cvt, i32* %b, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
 | |
|   ret void
 | |
| 
 | |
| ; REG3's definition is closer to movl than REG2's, but the pass still chooses
 | |
| ; REG2 because it provides the resultant address displacement fitting 1 byte.
 | |
| 
 | |
| }
 | |
| 
 | |
| define void @test4(i64 %x) nounwind minsize {
 | |
| ; ENABLED-LABEL: test4:
 | |
| ; ENABLED:       # %bb.0: # %entry
 | |
| ; ENABLED-NEXT:    imulq $12, %rdi, %rax
 | |
| ; ENABLED-NEXT:    leaq arr1+4(%rax), %rax
 | |
| ; ENABLED-NEXT:    movl -4(%rax), %ecx
 | |
| ; ENABLED-NEXT:    subl (%rax), %ecx
 | |
| ; ENABLED-NEXT:    addl 4(%rax), %ecx
 | |
| ; ENABLED-NEXT:    cmpl $2, %ecx
 | |
| ; ENABLED-NEXT:    je .LBB3_3
 | |
| ; ENABLED-NEXT:  # %bb.1: # %entry
 | |
| ; ENABLED-NEXT:    cmpl $1, %ecx
 | |
| ; ENABLED-NEXT:    jne .LBB3_4
 | |
| ; ENABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; ENABLED-NEXT:    movl $111, (%rax)
 | |
| ; ENABLED-NEXT:    movl $222, 4(%rax)
 | |
| ; ENABLED-NEXT:    retq
 | |
| ; ENABLED-NEXT:  .LBB3_3: # %sw.bb.2
 | |
| ; ENABLED-NEXT:    movl $333, (%rax) # imm = 0x14D
 | |
| ; ENABLED-NEXT:    movl $444, 4(%rax) # imm = 0x1BC
 | |
| ; ENABLED-NEXT:  .LBB3_4: # %sw.epilog
 | |
| ; ENABLED-NEXT:    retq
 | |
| ;
 | |
| ; DISABLED-LABEL: test4:
 | |
| ; DISABLED:       # %bb.0: # %entry
 | |
| ; DISABLED-NEXT:    imulq $12, %rdi, %rsi
 | |
| ; DISABLED-NEXT:    movl arr1(%rsi), %edx
 | |
| ; DISABLED-NEXT:    leaq arr1+4(%rsi), %rax
 | |
| ; DISABLED-NEXT:    subl arr1+4(%rsi), %edx
 | |
| ; DISABLED-NEXT:    leaq arr1+8(%rsi), %rcx
 | |
| ; DISABLED-NEXT:    addl arr1+8(%rsi), %edx
 | |
| ; DISABLED-NEXT:    cmpl $2, %edx
 | |
| ; DISABLED-NEXT:    je .LBB3_3
 | |
| ; DISABLED-NEXT:  # %bb.1: # %entry
 | |
| ; DISABLED-NEXT:    cmpl $1, %edx
 | |
| ; DISABLED-NEXT:    jne .LBB3_4
 | |
| ; DISABLED-NEXT:  # %bb.2: # %sw.bb.1
 | |
| ; DISABLED-NEXT:    movl $111, (%rax)
 | |
| ; DISABLED-NEXT:    movl $222, (%rcx)
 | |
| ; DISABLED-NEXT:    retq
 | |
| ; DISABLED-NEXT:  .LBB3_3: # %sw.bb.2
 | |
| ; DISABLED-NEXT:    movl $333, (%rax) # imm = 0x14D
 | |
| ; DISABLED-NEXT:    movl $444, (%rcx) # imm = 0x1BC
 | |
| ; DISABLED-NEXT:  .LBB3_4: # %sw.epilog
 | |
| ; DISABLED-NEXT:    retq
 | |
| entry:
 | |
|   %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
 | |
|   %tmp = load i32, i32* %a, align 4
 | |
|   %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
 | |
|   %tmp1 = load i32, i32* %b, align 4
 | |
|   %sub = sub i32 %tmp, %tmp1
 | |
|   %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
 | |
|   %tmp2 = load i32, i32* %c, align 4
 | |
|   %add = add nsw i32 %sub, %tmp2
 | |
|   switch i32 %add, label %sw.epilog [
 | |
|     i32 1, label %sw.bb.1
 | |
|     i32 2, label %sw.bb.2
 | |
|   ]
 | |
| 
 | |
| sw.bb.1:                                          ; preds = %entry
 | |
|   store i32 111, i32* %b, align 4
 | |
|   store i32 222, i32* %c, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.bb.2:                                          ; preds = %entry
 | |
|   store i32 333, i32* %b, align 4
 | |
|   store i32 444, i32* %c, align 4
 | |
|   br label %sw.epilog
 | |
| 
 | |
| sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define  i32 @test5(i32 %x, i32 %y)  #0 {
 | |
| ; CHECK-LABEL: test5:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    addl %esi, %esi
 | |
| ; CHECK-NEXT:    subl %esi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 %y, -2
 | |
|   %add = add nsw i32 %mul, %x
 | |
|   ret i32 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test6(i32 %x, i32 %y)  #0 {
 | |
| ; CHECK-LABEL: test6:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    leal (%rsi,%rsi,2), %ecx
 | |
| ; CHECK-NEXT:    subl %ecx, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 %y, -3
 | |
|   %add = add nsw i32 %mul, %x
 | |
|   ret i32 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test7(i32 %x, i32 %y)  #0 {
 | |
| ; CHECK-LABEL: test7:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    shll $2, %esi
 | |
| ; CHECK-NEXT:    subl %esi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 %y, -4
 | |
|   %add = add nsw i32 %mul, %x
 | |
|   ret i32 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test8(i32 %x, i32 %y)  #0 {
 | |
| ; CHECK-LABEL: test8:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
 | |
| ; CHECK-NEXT:    leal (,%rsi,4), %eax
 | |
| ; CHECK-NEXT:    subl %edi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = shl nsw i32 %y, 2
 | |
|   %sub = sub nsw i32 %mul, %x
 | |
|   ret i32 %sub
 | |
| }
 | |
| 
 | |
| 
 | |
| define  i32 @test9(i32 %x, i32 %y) #0 {
 | |
| ; CHECK-LABEL: test9:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    addl %esi, %esi
 | |
| ; CHECK-NEXT:    subl %esi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 -2, %y
 | |
|   %add = add nsw i32 %x, %mul
 | |
|   ret i32 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test10(i32 %x, i32 %y) #0 {
 | |
| ; CHECK-LABEL: test10:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    leal (%rsi,%rsi,2), %ecx
 | |
| ; CHECK-NEXT:    subl %ecx, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 -3, %y
 | |
|   %add = add nsw i32 %x, %mul
 | |
|   ret i32 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test11(i32 %x, i32 %y) #0 {
 | |
| ; CHECK-LABEL: test11:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    shll $2, %esi
 | |
| ; CHECK-NEXT:    subl %esi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 -4, %y
 | |
|   %add = add nsw i32 %x, %mul
 | |
|   ret i32 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test12(i32 %x, i32 %y) #0 {
 | |
| ; CHECK-LABEL: test12:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
 | |
| ; CHECK-NEXT:    leal (,%rsi,4), %eax
 | |
| ; CHECK-NEXT:    subl %edi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 4, %y
 | |
|   %sub = sub nsw i32 %mul, %x
 | |
|   ret i32 %sub
 | |
| }
 | |
| 
 | |
| define  i64 @test13(i64 %x, i64 %y) #0 {
 | |
| ; CHECK-LABEL: test13:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    movq %rdi, %rax
 | |
| ; CHECK-NEXT:    shlq $2, %rsi
 | |
| ; CHECK-NEXT:    subq %rsi, %rax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i64 -4, %y
 | |
|   %add = add nsw i64 %x, %mul
 | |
|   ret i64 %add
 | |
| }
 | |
| 
 | |
| define  i32 @test14(i32 %x, i32 %y) #0 {
 | |
| ; CHECK-LABEL: test14:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
 | |
| ; CHECK-NEXT:    leal (,%rsi,4), %eax
 | |
| ; CHECK-NEXT:    subl %edi, %eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %mul = mul nsw i32 4, %y
 | |
|   %sub = sub nsw i32 %mul, %x
 | |
|   ret i32 %sub
 | |
| }
 | |
| 
 | |
| define  zeroext i16 @test15(i16 zeroext %x, i16 zeroext %y) #0 {
 | |
| ; CHECK-LABEL: test15:
 | |
| ; CHECK:       # %bb.0: # %entry
 | |
| ; CHECK-NEXT:    movl %edi, %eax
 | |
| ; CHECK-NEXT:    shll $3, %esi
 | |
| ; CHECK-NEXT:    subl %esi, %eax
 | |
| ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
 | |
| ; CHECK-NEXT:    retq
 | |
| entry:
 | |
|   %conv = zext i16 %x to i32
 | |
|   %conv1 = zext i16 %y to i32
 | |
|   %mul = mul nsw i32 -8, %conv1
 | |
|   %add = add nsw i32 %conv, %mul
 | |
|   %conv2 = trunc i32 %add to i16
 | |
|   ret i16 %conv2
 | |
| }
 | |
| 
 | |
| attributes #0 = { norecurse nounwind optsize readnone uwtable}
 |