1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00
llvm-mirror/test/CodeGen/X86/loop-search.ll
David Bolvansky 3cca24cb63 [Codegen] Merge tail blocks with no successors after block placement
Summary:
I found the following case having tail blocks with no successors merging opportunities after block placement.

Before block placement:

bb0:
    ...
    bne a0, 0, bb2:

bb1:
    mv a0, 1
    ret 

bb2:
    ...

bb3:
    mv a0, 1
    ret

bb4:
    mv a0, -1
    ret

The conditional branch bne in bb0 is opposite to beq.

After block placement:

bb0:
    ...
    beq a0, 0, bb1

bb2:
    ...

bb4:
    mv a0, -1
    ret

bb1:
    mv a0, 1
    ret

bb3:
    mv a0, 1
    ret

After block placement, that appears new tail merging opportunity, bb1 and bb3 can be merged as one block. So the conditional constraint for merging tail blocks with no successors should be removed. In my experiment for RISC-V, it decreases code size.


Author of original patch: Jim Lin

Reviewers: haicheng, aheejin, craig.topper, rnk, RKSimon, Jim, dmgreen

Reviewed By: Jim, dmgreen

Subscribers: xbolva00, dschuff, javed.absar, sbc100, jgravelle-google, aheejin, kito-cheng, dmgreen, PkmX, llvm-commits

Tags: #llvm

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

llvm-svn: 363284
2019-06-13 18:11:32 +00:00

61 lines
2.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
; This test comes from PR27136
; We should hoist loop constant invariant
define zeroext i1 @search(i32 %needle, i32* nocapture readonly %haystack, i32 %count) {
; CHECK-LABEL: search:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: testl %edx, %edx
; CHECK-NEXT: jle LBB0_5
; CHECK-NEXT: ## %bb.1: ## %for.body.preheader
; CHECK-NEXT: movslq %edx, %rax
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: LBB0_2: ## %for.body
; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-NEXT: cmpl %edi, (%rsi,%rcx,4)
; CHECK-NEXT: je LBB0_6
; CHECK-NEXT: ## %bb.3: ## %for.cond
; CHECK-NEXT: ## in Loop: Header=BB0_2 Depth=1
; CHECK-NEXT: incq %rcx
; CHECK-NEXT: cmpq %rax, %rcx
; CHECK-NEXT: jl LBB0_2
; CHECK-NEXT: LBB0_5:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
; CHECK-NEXT: LBB0_6:
; CHECK-NEXT: movb $1, %al
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
entry:
%cmp5 = icmp sgt i32 %count, 0
br i1 %cmp5, label %for.body.preheader, label %cleanup
for.body.preheader: ; preds = %entry
%0 = sext i32 %count to i64
br label %for.body
for.cond: ; preds = %for.body
%cmp = icmp slt i64 %indvars.iv.next, %0
br i1 %cmp, label %for.body, label %cleanup.loopexit
for.body: ; preds = %for.body.preheader, %for.cond
%indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.cond ]
%arrayidx = getelementptr inbounds i32, i32* %haystack, i64 %indvars.iv
%1 = load i32, i32* %arrayidx, align 4
%cmp1 = icmp eq i32 %1, %needle
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br i1 %cmp1, label %cleanup.loopexit, label %for.cond
cleanup.loopexit: ; preds = %for.cond, %for.body
%.ph = phi i1 [ false, %for.cond ], [ true, %for.body ]
br label %cleanup
cleanup: ; preds = %cleanup.loopexit, %entry
%2 = phi i1 [ false, %entry ], [ %.ph, %cleanup.loopexit ]
ret i1 %2
}