1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00
llvm-mirror/test/CodeGen/X86/and-sink.ll
Amaury Sechet b89f706ba3 [DAGCOmbine] Ensure that (brcond (setcc ...)) is handled in a canonical manner.
Summary:
There are transformation that change setcc into other constructs, and transform that try to reconstruct a setcc from the brcond condition. Depending on what order these transform are done, the end result differs.

Most of the time, it is preferable to get a setcc as a brcond argument (and this is why brcond try to recreate the setcc in the first place) so we ensure this is done every time by also doing it at the setcc level when the only user is a brcond.

Reviewers: spatel, hfinkel, niravd, craig.topper

Subscribers: nhaehnle, llvm-commits

Differential Revision: https://reviews.llvm.org/D41235

llvm-svn: 325892
2018-02-23 11:50:42 +00:00

237 lines
6.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=i686-unknown -verify-machineinstrs < %s | FileCheck %s
; RUN: opt < %s -codegenprepare -S -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-CGP %s
@A = global i32 zeroinitializer
@B = global i32 zeroinitializer
@C = global i32 zeroinitializer
; Test that 'and' is sunk into bb0.
define i32 @and_sink1(i32 %a, i1 %c) {
; CHECK-LABEL: and_sink1:
; CHECK: # %bb.0:
; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
; CHECK-NEXT: je .LBB0_3
; CHECK-NEXT: # %bb.1: # %bb0
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: testb $4, %al
; CHECK-NEXT: movl $0, A
; CHECK-NEXT: jne .LBB0_3
; CHECK-NEXT: # %bb.2: # %bb1
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: retl
; CHECK-NEXT: .LBB0_3: # %bb2
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retl
; CHECK-CGP-LABEL: @and_sink1(
; CHECK-CGP-NOT: and i32
%and = and i32 %a, 4
br i1 %c, label %bb0, label %bb2
bb0:
; CHECK-CGP-LABEL: bb0:
; CHECK-CGP: and i32
; CHECK-CGP-NEXT: icmp eq i32
; CHECK-CGP-NEXT: store
; CHECK-CGP-NEXT: br
%cmp = icmp eq i32 %and, 0
store i32 0, i32* @A
br i1 %cmp, label %bb1, label %bb2
bb1:
ret i32 1
bb2:
ret i32 0
}
; Test that both 'and' and cmp get sunk to bb1.
define i32 @and_sink2(i32 %a, i1 %c, i1 %c2) {
; CHECK-LABEL: and_sink2:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $0, A
; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
; CHECK-NEXT: je .LBB1_5
; CHECK-NEXT: # %bb.1: # %bb0.preheader
; CHECK-NEXT: movb {{[0-9]+}}(%esp), %al
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB1_2: # %bb0
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movl $0, B
; CHECK-NEXT: testb $1, %al
; CHECK-NEXT: je .LBB1_5
; CHECK-NEXT: # %bb.3: # %bb1
; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT: testb $4, %cl
; CHECK-NEXT: movl $0, C
; CHECK-NEXT: jne .LBB1_2
; CHECK-NEXT: # %bb.4: # %bb2
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: retl
; CHECK-NEXT: .LBB1_5: # %bb3
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retl
; CHECK-CGP-LABEL: @and_sink2(
; CHECK-CGP-NOT: and i32
%and = and i32 %a, 4
store i32 0, i32* @A
br i1 %c, label %bb0, label %bb3
bb0:
; CHECK-CGP-LABEL: bb0:
; CHECK-CGP-NOT: and i32
; CHECK-CGP-NOT: icmp
%cmp = icmp eq i32 %and, 0
store i32 0, i32* @B
br i1 %c2, label %bb1, label %bb3
bb1:
; CHECK-CGP-LABEL: bb1:
; CHECK-CGP: and i32
; CHECK-CGP-NEXT: icmp eq i32
; CHECK-CGP-NEXT: store
; CHECK-CGP-NEXT: br
store i32 0, i32* @C
br i1 %cmp, label %bb2, label %bb0
bb2:
ret i32 1
bb3:
ret i32 0
}
; Test that CodeGenPrepare doesn't get stuck in a loop sinking and hoisting a masked load.
define i32 @and_sink3(i1 %c, i32* %p) {
; CHECK-LABEL: and_sink3:
; CHECK: # %bb.0:
; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
; CHECK-NEXT: je .LBB2_3
; CHECK-NEXT: # %bb.1: # %bb0
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: movzbl (%eax), %eax
; CHECK-NEXT: testl %eax, %eax
; CHECK-NEXT: movl $0, A
; CHECK-NEXT: je .LBB2_2
; CHECK-NEXT: .LBB2_3: # %bb2
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retl
; CHECK-NEXT: .LBB2_2: # %bb1
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: retl
; CHECK-CGP-LABEL: @and_sink3(
; CHECK-CGP: load i32
; CHECK-CGP-NEXT: and i32
%load = load i32, i32* %p
%and = and i32 %load, 255
br i1 %c, label %bb0, label %bb2
bb0:
; CHECK-CGP-LABEL: bb0:
; CHECK-CGP-NOT: and i32
; CHECK-CGP: icmp eq i32
%cmp = icmp eq i32 %and, 0
store i32 0, i32* @A
br i1 %cmp, label %bb1, label %bb2
bb1:
ret i32 1
bb2:
ret i32 0
}
; Test that CodeGenPrepare sinks/duplicates non-immediate 'and'.
define i32 @and_sink4(i32 %a, i32 %b, i1 %c) {
; CHECK-LABEL: and_sink4:
; CHECK: # %bb.0:
; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
; CHECK-NEXT: je .LBB3_4
; CHECK-NEXT: # %bb.1: # %bb0
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
; CHECK-NEXT: testl %eax, %ecx
; CHECK-NEXT: movl $0, A
; CHECK-NEXT: jne .LBB3_4
; CHECK-NEXT: # %bb.2: # %bb1
; CHECK-NEXT: leal (%ecx,%eax), %edx
; CHECK-NEXT: testl %eax, %ecx
; CHECK-NEXT: movl %edx, B
; CHECK-NEXT: je .LBB3_3
; CHECK-NEXT: .LBB3_4: # %bb3
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retl
; CHECK-NEXT: .LBB3_3: # %bb2
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: retl
; CHECK-CGP-LABEL: @and_sink4(
; CHECK-CGP-NOT: and i32
; CHECK-CGP-NOT: icmp
%and = and i32 %a, %b
%cmp = icmp eq i32 %and, 0
br i1 %c, label %bb0, label %bb3
bb0:
; CHECK-CGP-LABEL: bb0:
; CHECK-CGP: and i32
; CHECK-CGP-NEXT: icmp eq i32
store i32 0, i32* @A
br i1 %cmp, label %bb1, label %bb3
bb1:
; CHECK-CGP-LABEL: bb1:
; CHECK-CGP: and i32
; CHECK-CGP-NEXT: icmp eq i32
%add = add i32 %a, %b
store i32 %add, i32* @B
br i1 %cmp, label %bb2, label %bb3
bb2:
ret i32 1
bb3:
ret i32 0
}
; Test that CodeGenPrepare doesn't sink/duplicate non-immediate 'and'
; when it would increase register pressure.
define i32 @and_sink5(i32 %a, i32 %b, i32 %a2, i32 %b2, i1 %c) {
; CHECK-LABEL: and_sink5:
; CHECK: # %bb.0:
; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
; CHECK-NEXT: je .LBB4_4
; CHECK-NEXT: # %bb.1: # %bb0
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: andl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: movl $0, A
; CHECK-NEXT: jne .LBB4_4
; CHECK-NEXT: # %bb.2: # %bb1
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
; CHECK-NEXT: addl {{[0-9]+}}(%esp), %ecx
; CHECK-NEXT: testl %eax, %eax
; CHECK-NEXT: movl %ecx, B
; CHECK-NEXT: je .LBB4_3
; CHECK-NEXT: .LBB4_4: # %bb3
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retl
; CHECK-NEXT: .LBB4_3: # %bb2
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: retl
; CHECK-CGP-LABEL: @and_sink5(
; CHECK-CGP: and i32
; CHECK-CGP-NOT: icmp
%and = and i32 %a, %b
%cmp = icmp eq i32 %and, 0
br i1 %c, label %bb0, label %bb3
bb0:
; CHECK-CGP-LABEL: bb0:
; CHECK-CGP-NOT: and i32
; CHECK-CGP: icmp eq i32
store i32 0, i32* @A
br i1 %cmp, label %bb1, label %bb3
bb1:
; CHECK-CGP-LABEL: bb1:
; CHECK-CGP-NOT: and i32
; CHECK-CGP: icmp eq i32
%add = add i32 %a2, %b2
store i32 %add, i32* @B
br i1 %cmp, label %bb2, label %bb3
bb2:
ret i32 1
bb3:
ret i32 0
}