Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 1 | ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 2 | |
| 3 | ; The addrecs in this loop are analyzable only by using nsw information. |
| 4 | |
| 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" |
| 6 | |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 7 | ; CHECK: Classifying expressions for: @test1 |
| 8 | define void @test1(double* %p) nounwind { |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 9 | entry: |
| 10 | %tmp = load double* %p, align 8 ; <double> [#uses=1] |
| 11 | %tmp1 = fcmp ogt double %tmp, 2.000000e+00 ; <i1> [#uses=1] |
| 12 | br i1 %tmp1, label %bb.nph, label %return |
| 13 | |
| 14 | bb.nph: ; preds = %entry |
| 15 | br label %bb |
| 16 | |
| 17 | bb: ; preds = %bb1, %bb.nph |
| 18 | %i.01 = phi i32 [ %tmp8, %bb1 ], [ 0, %bb.nph ] ; <i32> [#uses=3] |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 19 | ; CHECK: %i.01 |
| 20 | ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb> |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 21 | %tmp2 = sext i32 %i.01 to i64 ; <i64> [#uses=1] |
| 22 | %tmp3 = getelementptr double* %p, i64 %tmp2 ; <double*> [#uses=1] |
| 23 | %tmp4 = load double* %tmp3, align 8 ; <double> [#uses=1] |
| 24 | %tmp5 = fmul double %tmp4, 9.200000e+00 ; <double> [#uses=1] |
| 25 | %tmp6 = sext i32 %i.01 to i64 ; <i64> [#uses=1] |
| 26 | %tmp7 = getelementptr double* %p, i64 %tmp6 ; <double*> [#uses=1] |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 27 | ; CHECK: %tmp7 |
| 28 | ; CHECK-NEXT: --> {%p,+,8}<%bb> |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 29 | store double %tmp5, double* %tmp7, align 8 |
Dan Gohman | 59858cf | 2009-07-27 16:11:46 +0000 | [diff] [blame] | 30 | %tmp8 = add nsw i32 %i.01, 1 ; <i32> [#uses=2] |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 31 | ; CHECK: %tmp8 |
| 32 | ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%bb> |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 33 | br label %bb1 |
| 34 | |
| 35 | bb1: ; preds = %bb |
| 36 | %phitmp = sext i32 %tmp8 to i64 ; <i64> [#uses=1] |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 37 | ; CHECK: %phitmp |
Andrew Trick | c343c1e | 2011-03-15 00:37:00 +0000 | [diff] [blame] | 38 | ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%bb> |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 39 | %tmp9 = getelementptr double* %p, i64 %phitmp ; <double*> [#uses=1] |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 40 | ; CHECK: %tmp9 |
| 41 | ; CHECK-NEXT: --> {(8 + %p),+,8}<%bb> |
Dan Gohman | eb490a7 | 2009-07-25 01:22:26 +0000 | [diff] [blame] | 42 | %tmp10 = load double* %tmp9, align 8 ; <double> [#uses=1] |
| 43 | %tmp11 = fcmp ogt double %tmp10, 2.000000e+00 ; <i1> [#uses=1] |
| 44 | br i1 %tmp11, label %bb, label %bb1.return_crit_edge |
| 45 | |
| 46 | bb1.return_crit_edge: ; preds = %bb1 |
| 47 | br label %return |
| 48 | |
| 49 | return: ; preds = %bb1.return_crit_edge, %entry |
| 50 | ret void |
| 51 | } |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 52 | |
| 53 | ; CHECK: Classifying expressions for: @test2 |
| 54 | define void @test2(i32* %begin, i32* %end) ssp { |
| 55 | entry: |
| 56 | %cmp1.i.i = icmp eq i32* %begin, %end |
| 57 | br i1 %cmp1.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.lr.ph.i.i |
| 58 | |
| 59 | for.body.lr.ph.i.i: ; preds = %entry |
| 60 | br label %for.body.i.i |
| 61 | |
| 62 | for.body.i.i: ; preds = %for.body.i.i, %for.body.lr.ph.i.i |
| 63 | %__first.addr.02.i.i = phi i32* [ %begin, %for.body.lr.ph.i.i ], [ %ptrincdec.i.i, %for.body.i.i ] |
| 64 | ; CHECK: %__first.addr.02.i.i |
Andrew Trick | c343c1e | 2011-03-15 00:37:00 +0000 | [diff] [blame] | 65 | ; CHECK-NEXT: --> {%begin,+,4}<nw><%for.body.i.i> |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 66 | store i32 0, i32* %__first.addr.02.i.i, align 4 |
| 67 | %ptrincdec.i.i = getelementptr inbounds i32* %__first.addr.02.i.i, i64 1 |
| 68 | ; CHECK: %ptrincdec.i.i |
Andrew Trick | c343c1e | 2011-03-15 00:37:00 +0000 | [diff] [blame] | 69 | ; CHECK-NEXT: --> {(4 + %begin),+,4}<nw><%for.body.i.i> |
Chris Lattner | 6d5a241 | 2011-01-09 02:28:48 +0000 | [diff] [blame] | 70 | %cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end |
| 71 | br i1 %cmp.i.i, label %for.cond.for.end_crit_edge.i.i, label %for.body.i.i |
| 72 | |
| 73 | for.cond.for.end_crit_edge.i.i: ; preds = %for.body.i.i |
| 74 | br label %_ZSt4fillIPiiEvT_S1_RKT0_.exit |
| 75 | |
| 76 | _ZSt4fillIPiiEvT_S1_RKT0_.exit: ; preds = %entry, %for.cond.for.end_crit_edge.i.i |
| 77 | ret void |
| 78 | } |
Chris Lattner | 8ebaf90 | 2011-02-13 03:14:49 +0000 | [diff] [blame] | 79 | |
| 80 | ; Various checks for inbounds geps. |
| 81 | define void @test3(i32* %begin, i32* %end) nounwind ssp { |
| 82 | entry: |
| 83 | %cmp7.i.i = icmp eq i32* %begin, %end |
| 84 | br i1 %cmp7.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i |
| 85 | |
| 86 | for.body.i.i: ; preds = %entry, %for.body.i.i |
| 87 | %indvar.i.i = phi i64 [ %tmp, %for.body.i.i ], [ 0, %entry ] |
| 88 | ; CHECK: %indvar.i.i |
| 89 | ; CHECK: {0,+,1}<nuw><nsw><%for.body.i.i> |
| 90 | %tmp = add nsw i64 %indvar.i.i, 1 |
Andrew Trick | c343c1e | 2011-03-15 00:37:00 +0000 | [diff] [blame] | 91 | ; CHECK: %tmp = |
Chris Lattner | 8ebaf90 | 2011-02-13 03:14:49 +0000 | [diff] [blame] | 92 | ; CHECK: {1,+,1}<nuw><nsw><%for.body.i.i> |
| 93 | %ptrincdec.i.i = getelementptr inbounds i32* %begin, i64 %tmp |
| 94 | ; CHECK: %ptrincdec.i.i = |
Benjamin Kramer | 86df062 | 2012-04-17 06:33:57 +0000 | [diff] [blame] | 95 | ; CHECK: {(4 + %begin),+,4}<nsw><%for.body.i.i> |
Chris Lattner | 8ebaf90 | 2011-02-13 03:14:49 +0000 | [diff] [blame] | 96 | %__first.addr.08.i.i = getelementptr inbounds i32* %begin, i64 %indvar.i.i |
| 97 | ; CHECK: %__first.addr.08.i.i |
Benjamin Kramer | 86df062 | 2012-04-17 06:33:57 +0000 | [diff] [blame] | 98 | ; CHECK: {%begin,+,4}<nsw><%for.body.i.i> |
Chris Lattner | 8ebaf90 | 2011-02-13 03:14:49 +0000 | [diff] [blame] | 99 | store i32 0, i32* %__first.addr.08.i.i, align 4 |
| 100 | %cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end |
| 101 | br i1 %cmp.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i |
Andrew Trick | c343c1e | 2011-03-15 00:37:00 +0000 | [diff] [blame] | 102 | ; CHECK: Loop %for.body.i.i: backedge-taken count is ((-4 + (-1 * %begin) + %end) /u 4) |
| 103 | ; CHECK: Loop %for.body.i.i: max backedge-taken count is ((-4 + (-1 * %begin) + %end) /u 4) |
Chris Lattner | 8ebaf90 | 2011-02-13 03:14:49 +0000 | [diff] [blame] | 104 | _ZSt4fillIPiiEvT_S1_RKT0_.exit: ; preds = %for.body.i.i, %entry |
| 105 | ret void |
Andrew Trick | ecb35ec | 2011-11-29 02:16:38 +0000 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | ; A single AddExpr exists for (%a + %b), which is not always <nsw>. |
| 109 | ; CHECK: @addnsw |
| 110 | ; CHECK-NOT: --> (%a + %b)<nsw> |
| 111 | define i32 @addnsw(i32 %a, i32 %b) nounwind ssp { |
| 112 | entry: |
| 113 | %tmp = add i32 %a, %b |
| 114 | %cmp = icmp sgt i32 %tmp, 0 |
| 115 | br i1 %cmp, label %greater, label %exit |
| 116 | |
| 117 | greater: |
| 118 | %tmp2 = add nsw i32 %a, %b |
| 119 | br label %exit |
| 120 | |
| 121 | exit: |
| 122 | %result = phi i32 [ %a, %entry ], [ %tmp2, %greater ] |
| 123 | ret i32 %result |
| 124 | } |