Files
Serguei Katkov e82a7f1476 [CGP] Disable Select instruction handling in optimizeMemoryInst. NFC
This patch disables the handling of selects in optimization
extensing scope of optimizeMemoryInst.

The optimization itself is disable by default.
The idea here is just to switch optimiztion level step by step.

Specifically, first optimization will be enabled only for Phi nodes,
then select instructions will be added.

In case someone will complain about perfromance it will be easier to
detect what part of optimizations is responsible for that.

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



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317555 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-07 09:43:08 +00:00

476 lines
13 KiB
LLVM

; RUN: opt -S -codegenprepare -disable-complex-addr-modes=false -addr-sink-new-phis=true -addr-sink-new-select=true %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-YES
; RUN: opt -S -codegenprepare -disable-complex-addr-modes=false -addr-sink-new-phis=false -addr-sink-new-select=true %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"
; Can we sink for different base if there is no phi for base?
define i32 @test1(i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test1
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO: phi
; CHECK-NO-NEXT: load
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%v = load i32, i32* %c, align 4
ret i32 %v
}
; Can we sink for different base if there is phi for base?
define i32 @test2(i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test2
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK: getelementptr i8, {{.+}} 40
%b = phi i64* [%b1, %entry], [%b2, %if.then]
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%v = load i32, i32* %c, align 4
ret i32 %v
}
; Can we sink for different base if there is phi for base but not valid one?
define i32 @test3(i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test3
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO: phi
; CHECK-NO: phi
; CHECK-NO-NEXT: load
%b = phi i64* [%b2, %entry], [%b1, %if.then]
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%v = load i32, i32* %c, align 4
ret i32 %v
}
; Can we sink for different base if both addresses are in the same block?
define i32 @test4(i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test4
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO: phi
; CHECK-NO-NEXT: load
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%v = load i32, i32* %c, align 4
ret i32 %v
}
; Can we sink for different base if there is phi for base?
; Both addresses are in the same block.
define i32 @test5(i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test5
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
br label %fallthrough
fallthrough:
; CHECK: getelementptr i8, {{.+}} 40
%b = phi i64* [%b1, %entry], [%b2, %if.then]
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%v = load i32, i32* %c, align 4
ret i32 %v
}
; Can we sink for different base if there is phi for base but not valid one?
; Both addresses are in the same block.
define i32 @test6(i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test6
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO: phi
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: load
%b = phi i64* [%b2, %entry], [%b1, %if.then]
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%v = load i32, i32* %c, align 4
ret i32 %v
}
; case with a loop. No phi node.
define i32 @test7(i32 %N, i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test7
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br label %loop
loop:
; CHECK-LABEL: loop:
; CHECK-YES: sunk_phi
%iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]
%c3 = phi i32* [%c1, %entry], [%c, %fallthrough]
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO: phi
; CHECK-NO-NEXT: load
%c = phi i32* [%c3, %loop], [%c2, %if.then]
%v = load volatile i32, i32* %c, align 4
%iv.inc = add i32 %iv, 1
%cmp = icmp slt i32 %iv.inc, %N
br i1 %cmp, label %loop, label %exit
exit:
ret i32 %v
}
; case with a loop. There is phi node.
define i32 @test8(i32 %N, i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test8
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br label %loop
loop:
%iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]
%c3 = phi i32* [%c1, %entry], [%c, %fallthrough]
%b3 = phi i64* [%b1, %entry], [%b, %fallthrough]
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK: getelementptr i8, {{.+}} 40
%c = phi i32* [%c3, %loop], [%c2, %if.then]
%b = phi i64* [%b3, %loop], [%b2, %if.then]
%v = load volatile i32, i32* %c, align 4
%iv.inc = add i32 %iv, 1
%cmp = icmp slt i32 %iv.inc, %N
br i1 %cmp, label %loop, label %exit
exit:
ret i32 %v
}
; case with a loop. There is phi node but it does not fit.
define i32 @test9(i32 %N, i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test9
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br label %loop
loop:
; CHECK-LABEL: loop:
; CHECK-YES: sunk_phi
%iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]
%c3 = phi i32* [%c1, %entry], [%c, %fallthrough]
%b3 = phi i64* [%b1, %entry], [%b2, %fallthrough]
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO: phi
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: load
%c = phi i32* [%c3, %loop], [%c2, %if.then]
%b = phi i64* [%b3, %loop], [%b2, %if.then]
%v = load volatile i32, i32* %c, align 4
%iv.inc = add i32 %iv, 1
%cmp = icmp slt i32 %iv.inc, %N
br i1 %cmp, label %loop, label %exit
exit:
ret i32 %v
}
; Case through a loop. No phi node.
define i32 @test10(i32 %N, i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test10
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: br
%c = phi i32* [%c1, %entry], [%c2, %if.then]
br label %loop
loop:
%iv = phi i32 [0, %fallthrough], [%iv.inc, %loop]
%iv.inc = add i32 %iv, 1
%cmp = icmp slt i32 %iv.inc, %N
br i1 %cmp, label %loop, label %exit
exit:
; CHECK-YES: sunkaddr
%v = load volatile i32, i32* %c, align 4
ret i32 %v
}
; Case through a loop. There is a phi.
define i32 @test11(i32 %N, i1 %cond, i64* %b1, i64* %b2) {
; CHECK-LABEL: @test11
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK: phi
; CHECK: phi
; CHECK: br
%c = phi i32* [%c1, %entry], [%c2, %if.then]
%b = phi i64* [%b1, %entry], [%b2, %if.then]
br label %loop
loop:
%iv = phi i32 [0, %fallthrough], [%iv.inc, %loop]
%iv.inc = add i32 %iv, 1
%cmp = icmp slt i32 %iv.inc, %N
br i1 %cmp, label %loop, label %exit
exit:
; CHECK: sunkaddr
%v = load volatile i32, i32* %c, align 4
ret i32 %v
}
; Complex case with address value from previous iteration.
define i32 @test12(i32 %N, i1 %cond, i64* %b1, i64* %b2, i64* %b3) {
; CHECK-LABEL: @test12
entry:
%a1 = getelementptr inbounds i64, i64* %b1, i64 5
%c1 = bitcast i64* %a1 to i32*
br label %loop
loop:
; CHECK-LABEL: loop:
; CHECK-YES: sunk_phi
; CHECK-NO: phi
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: br
%iv = phi i32 [0, %entry], [%iv.inc, %backedge]
%c3 = phi i32* [%c1, %entry], [%c, %backedge]
%b4 = phi i64* [%b1, %entry], [%b5, %backedge]
br i1 %cond, label %if.then, label %fallthrough
if.then:
%a2 = getelementptr inbounds i64, i64* %b2, i64 5
%c2 = bitcast i64* %a2 to i32*
br label %fallthrough
fallthrough:
; CHECK-LABEL: fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO: phi
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: load
%c = phi i32* [%c3, %loop], [%c2, %if.then]
%b6 = phi i64* [%b4, %loop], [%b2, %if.then]
%v = load volatile i32, i32* %c, align 4
%a4 = getelementptr inbounds i64, i64* %b4, i64 5
%c4 = bitcast i64* %a4 to i32*
%cmp = icmp slt i32 %iv, 20
br i1 %cmp, label %backedge, label %if.then.2
if.then.2:
br label %backedge
backedge:
%b5 = phi i64* [%b4, %fallthrough], [%b6, %if.then.2]
%iv.inc = add i32 %iv, 1
%cmp2 = icmp slt i32 %iv.inc, %N
br i1 %cmp2, label %loop, label %exit
exit:
ret i32 %v
}
%struct.S = type {i32, i32}
; Case with index
define i32 @test13(i1 %cond, %struct.S* %b1, %struct.S* %b2, i64 %Index) {
; CHECK-LABEL: @test13
entry:
%a1 = getelementptr inbounds %struct.S, %struct.S* %b1, i64 %Index, i32 1
br i1 %cond, label %if.then, label %fallthrough
if.then:
%i2 = mul i64 %Index, 2
%a2 = getelementptr inbounds %struct.S, %struct.S* %b2, i64 %Index, i32 1
br label %fallthrough
fallthrough:
; CHECK-YES: sunk_phi
; CHECK-NO-LABEL: fallthrough:
; CHECK-NO-NEXT: phi
; CHECK-NO-NEXT: load
%a = phi i32* [%a1, %entry], [%a2, %if.then]
%v = load i32, i32* %a, align 4
ret i32 %v
}
; Select of Select case.
define i64 @test14(i1 %c1, i1 %c2, i64* %b1, i64* %b2, i64* %b3) {
; CHECK-LABEL: @test14
entry:
; CHECK-LABEL: entry:
%g1 = getelementptr inbounds i64, i64* %b1, i64 5
%g2 = getelementptr inbounds i64, i64* %b2, i64 5
%g3 = getelementptr inbounds i64, i64* %b3, i64 5
%s1 = select i1 %c1, i64* %g1, i64* %g2
%s2 = select i1 %c2, i64* %s1, i64* %g3
; CHECK: sunkaddr
%v = load i64 , i64* %s2, align 8
ret i64 %v
}
; Select of Phi case.
define i64 @test15(i1 %c1, i1 %c2, i64* %b1, i64* %b2, i64* %b3) {
; CHECK-LABEL: @test15
entry:
%g1 = getelementptr inbounds i64, i64* %b1, i64 5
%g2 = getelementptr inbounds i64, i64* %b2, i64 5
%g3 = getelementptr inbounds i64, i64* %b3, i64 5
br i1 %c1, label %if.then, label %fallthrough
if.then:
br label %fallthrough
fallthrough:
; CHECK-LABEL: fallthrough:
%p1 = phi i64* [%g1, %entry], [%g2, %if.then]
%s1 = select i1 %c2, i64* %p1, i64* %g3
; CHECK-YES: sunkaddr
; CHECK-NO: phi
; CHECK-NO-NEXT: select
; CHECK-NO-NEXT: load
%v = load i64 , i64* %s1, align 8
ret i64 %v
}
; Select of Phi case. Phi exists
define i64 @test16(i1 %c1, i1 %c2, i64* %b1, i64* %b2, i64* %b3) {
; CHECK-LABEL: @test16
entry:
%g1 = getelementptr inbounds i64, i64* %b1, i64 5
%g2 = getelementptr inbounds i64, i64* %b2, i64 5
%g3 = getelementptr inbounds i64, i64* %b3, i64 5
br i1 %c1, label %if.then, label %fallthrough
if.then:
br label %fallthrough
fallthrough:
; CHECK-LABEL: fallthrough:
%p = phi i64* [%b1, %entry], [%b2, %if.then]
%p1 = phi i64* [%g1, %entry], [%g2, %if.then]
%s1 = select i1 %c2, i64* %p1, i64* %g3
; CHECK: sunkaddr
%v = load i64 , i64* %s1, align 8
ret i64 %v
}
; Phi of Select case.
define i64 @test17(i1 %c1, i1 %c2, i64* %b1, i64* %b2, i64* %b3) {
; CHECK-LABEL: @test17
entry:
%g1 = getelementptr inbounds i64, i64* %b1, i64 5
%g2 = getelementptr inbounds i64, i64* %b2, i64 5
%g3 = getelementptr inbounds i64, i64* %b3, i64 5
%s1 = select i1 %c2, i64* %g1, i64* %g2
br i1 %c1, label %if.then, label %fallthrough
if.then:
br label %fallthrough
fallthrough:
; CHECK-LABEL: fallthrough:
%p1 = phi i64* [%s1, %entry], [%g3, %if.then]
; CHECK-YES: sunkaddr
; CHECK-NO: phi
; CHECK-NO-NEXT: load
%v = load i64 , i64* %p1, align 8
ret i64 %v
}