1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
; RUN: opt -passes='loop-mssa(licm)' -S %s | FileCheck %s --check-prefixes CHECK,LICM
; RUN: opt -passes='loop-mssa(lnicm)' -S %s | FileCheck %s --check-prefixes CHECK,LNICM
; This test represents the following function:
;
; double sin(double);
; int abs(int);
; double test(double x, int y[10]) {
; double t = 0; int s = 0;
; for (int i = 0; i < 10; i++) {
; for (int j = 0; j < 10; j++) {
; t = sin(x);
; s = abs(i);
; }
; y[i] = s;
; }
; return t;
; }
;
; We only want to sink the call of sin out of the loop nest.
; LICM also sinks the call of abs out of j-loop, but LNICM doesn't do so
; to try to make a perfect loop nest. (though y[i] = s; still prevents the
; loop nest from being a perfect loop nest in this test case)
define dso_local double @test(double %x, ptr noalias %y) {
entry:
br label %for.body
for.body:
%i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
br label %for.body3
; CHECK: for.body3:
; LNICM: call i32 @abs(i32 %i.02)
; LICM-NOT: call i32 @abs(i32 %i.02)
for.body3:
%j.01 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ]
%call = call double @sin(double %x)
%call4 = call i32 @abs(i32 %i.02)
%inc = add nsw i32 %j.01, 1
%cmp2 = icmp slt i32 %inc, 10
br i1 %cmp2, label %for.body3, label %for.end
; CHECK: for.end:
; LICM: call i32 @abs(i32 %i.02)
; LNICM-NOT: call i32 @abs(i32 %i.02)
for.end:
%s.1.lcssa = phi i32 [ %call4, %for.body3 ]
%t.1.lcssa = phi double [ %call, %for.body3 ]
%idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32, ptr %y, i64 %idxprom
store i32 %s.1.lcssa, ptr %arrayidx, align 4
%inc6 = add nsw i32 %i.02, 1
%cmp = icmp slt i32 %inc6, 10
br i1 %cmp, label %for.body, label %for.end7
; CHECK: for.end7:
; CHECK: call double @sin(double %x)
for.end7:
%t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
ret double %t.0.lcssa
}
; double sin(double);
; int abs(int);
; double test(double x, int y[10]) {
; double t = 0; int s = 0;
; for (int i = 0; i < 10; i++) {
; for (int k = 0; k < 10; k++) {
; for (int j = 0; j < 10; j++) {
; t = sin(x);
; s = abs(i);
; }
; }
; y[i] = s;
; }
; return t;
; }
;
define dso_local double @test2(double %x, ptr noalias %y) {
entry:
br label %for.body
for.body:
%i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
br label %for.k
for.k:
%k = phi i64 [ 0, %for.body ], [ %inc.k, %for.end.k ]
br label %for.body3
; CHECK: for.body3:
; LNICM: call i32 @abs(i32 %i.02)
; LICM-NOT: call i32 @abs(i32 %i.02)
for.body3:
%j.01 = phi i32 [ 0, %for.k ], [ %inc, %for.body3 ]
%call = call double @sin(double %x)
%call4 = call i32 @abs(i32 %i.02)
%inc = add nsw i32 %j.01, 1
%cmp2 = icmp slt i32 %inc, 10
br i1 %cmp2, label %for.body3, label %for.end.k
for.end.k:
%s.lcssa.k = phi i32 [ %call4, %for.body3 ]
%t.lcssa.k = phi double [ %call, %for.body3 ]
%inc.k = add nsw i64 %k, 1
%cmp.k = icmp slt i64 %inc.k, 10
br i1 %cmp.k, label %for.k, label %for.end
; CHECK: for.end:
; LICM: call i32 @abs(i32 %i.02)
; LNICM-NOT: call i32 @abs(i32 %i.02)
for.end:
%s.1.lcssa = phi i32 [ %s.lcssa.k, %for.end.k ]
%t.1.lcssa = phi double [ %t.lcssa.k, %for.end.k ]
%idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32, ptr %y, i64 %idxprom
store i32 %s.1.lcssa, ptr %arrayidx, align 4
%inc6 = add nsw i32 %i.02, 1
%cmp = icmp slt i32 %inc6, 10
br i1 %cmp, label %for.body, label %for.end7
; CHECK: for.end7:
; CHECK: call double @sin(double %x)
for.end7:
%t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
ret double %t.0.lcssa
}
declare dso_local double @sin(double) #0
declare dso_local i32 @abs(i32) #0
attributes #0 = { nounwind readnone willreturn }
|