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

155 lines
4.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s
; This file tests following optimization
;
; leal (%rdx,%rax), %esi
; subl %esi, %ecx
;
; can be transformed to
;
; subl %edx, %ecx
; subl %eax, %ecx
; TODO: replace lea with sub.
; C - (A + B) --> C - A - B
define i32 @test1(i32* %p, i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: test1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $edx killed $edx def $rdx
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: leal (%rdx,%rax), %esi
; CHECK-NEXT: subl %esi, %ecx
; CHECK-NEXT: movl %ecx, (%rdi)
; CHECK-NEXT: subl %edx, %eax
; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
; CHECK-NEXT: retq
entry:
%0 = add i32 %b, %a
%sub = sub i32 %c, %0
store i32 %sub, i32* %p, align 4
%sub1 = sub i32 %a, %b
ret i32 %sub1
}
; TODO: replace lea with add.
; (A + B) + C --> C + A + B
define i32 @test2(i32* %p, i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: test2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $edx killed $edx def $rdx
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: leal (%rax,%rdx), %esi
; CHECK-NEXT: addl %ecx, %esi
; CHECK-NEXT: movl %esi, (%rdi)
; CHECK-NEXT: subl %edx, %eax
; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
; CHECK-NEXT: retq
entry:
%0 = add i32 %a, %b
%1 = add i32 %c, %0
store i32 %1, i32* %p, align 4
%sub1 = sub i32 %a, %b
ret i32 %sub1
}
; TODO: replace lea with add.
; C + (A + B) --> C + A + B
define i32 @test3(i32* %p, i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: test3:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $edx killed $edx def $rdx
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: leal (%rax,%rdx), %esi
; CHECK-NEXT: addl %ecx, %esi
; CHECK-NEXT: movl %esi, (%rdi)
; CHECK-NEXT: subl %edx, %eax
; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
; CHECK-NEXT: retq
entry:
%0 = add i32 %a, %b
%1 = add i32 %0, %c
store i32 %1, i32* %p, align 4
%sub1 = sub i32 %a, %b
ret i32 %sub1
}
; (A + B) - C
; Can't be converted to A - C + B without introduce MOV
define i32 @test4(i32* %p, i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: test4:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $edx killed $edx def $rdx
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: leal (%rdx,%rax), %esi
; CHECK-NEXT: subl %ecx, %esi
; CHECK-NEXT: movl %esi, (%rdi)
; CHECK-NEXT: subl %edx, %eax
; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
; CHECK-NEXT: retq
entry:
%0 = add i32 %b, %a
%sub = sub i32 %0, %c
store i32 %sub, i32* %p, align 4
%sub1 = sub i32 %a, %b
ret i32 %sub1
}
; TODO: replace lea with sub.
define i64 @test5(i64* %p, i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: test5:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: leaq (%rdx,%rax), %rsi
; CHECK-NEXT: subq %rsi, %rcx
; CHECK-NEXT: movq %rcx, (%rdi)
; CHECK-NEXT: subq %rdx, %rax
; CHECK-NEXT: retq
entry:
%ld = load i64, i64* %p, align 8
%0 = add i64 %b, %ld
%sub = sub i64 %c, %0
store i64 %sub, i64* %p, align 8
%sub1 = sub i64 %ld, %b
ret i64 %sub1
}
; TODO: replace lea with add.
define i64 @test6(i64* %p, i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: test6:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: leaq (%rdx,%rax), %rsi
; CHECK-NEXT: addq %rcx, %rsi
; CHECK-NEXT: movq %rsi, (%rdi)
; CHECK-NEXT: subq %rdx, %rax
; CHECK-NEXT: retq
entry:
%ld = load i64, i64* %p, align 8
%0 = add i64 %b, %ld
%1 = add i64 %0, %c
store i64 %1, i64* %p, align 8
%sub1 = sub i64 %ld, %b
ret i64 %sub1
}
; TODO: replace lea with add.
define i64 @test7(i64* %p, i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: test7:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: leaq (%rdx,%rax), %rsi
; CHECK-NEXT: addq %rcx, %rsi
; CHECK-NEXT: movq %rsi, (%rdi)
; CHECK-NEXT: subq %rdx, %rax
; CHECK-NEXT: retq
entry:
%ld = load i64, i64* %p, align 8
%0 = add i64 %b, %ld
%1 = add i64 %c, %0
store i64 %1, i64* %p, align 8
%sub1 = sub i64 %ld, %b
ret i64 %sub1
}