llvm-project/llvm/test/CodeGen/X86/lea-opt.ll

310 lines
11 KiB
LLVM
Raw Normal View History

; 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
}