1 ; RUN: opt %s -always-inline | opt -analyze -scalar-evolution 2 ; There was optimization bug in ScalarEvolution, that causes too long 3 ; compute time and stack overflow crash. 4 5 declare void @body(i32) 6 declare void @llvm.assume(i1) 7 8 define available_externally void @assume1(i64 %i.ext, i64 %a) alwaysinline { 9 %cmp0 = icmp ne i64 %i.ext, %a 10 call void @llvm.assume(i1 %cmp0) 11 12 %a1 = add i64 %a, 1 13 %cmp1 = icmp ne i64 %i.ext, %a1 14 call void @llvm.assume(i1 %cmp1) 15 16 %a2 = add i64 %a1, 1 17 %cmp2 = icmp ne i64 %i.ext, %a2 18 call void @llvm.assume(i1 %cmp2) 19 20 %a3 = add i64 %a2, 1 21 %cmp3 = icmp ne i64 %i.ext, %a3 22 call void @llvm.assume(i1 %cmp3) 23 24 %a4 = add i64 %a3, 1 25 %cmp4 = icmp ne i64 %i.ext, %a4 26 call void @llvm.assume(i1 %cmp4) 27 28 ret void 29 } 30 31 define available_externally void @assume2(i64 %i.ext, i64 %a) alwaysinline { 32 call void @assume1(i64 %i.ext, i64 %a) 33 34 %a1 = add i64 %a, 5 35 %cmp1 = icmp ne i64 %i.ext, %a1 36 call void @assume1(i64 %i.ext, i64 %a1) 37 38 %a2 = add i64 %a1, 5 39 %cmp2 = icmp ne i64 %i.ext, %a2 40 call void @assume1(i64 %i.ext, i64 %a2) 41 42 %a3 = add i64 %a2, 5 43 %cmp3 = icmp ne i64 %i.ext, %a3 44 call void @assume1(i64 %i.ext, i64 %a3) 45 46 %a4 = add i64 %a3, 5 47 %cmp4 = icmp ne i64 %i.ext, %a4 48 call void @assume1(i64 %i.ext, i64 %a4) 49 50 ret void 51 } 52 53 define available_externally void @assume3(i64 %i.ext, i64 %a) alwaysinline { 54 call void @assume2(i64 %i.ext, i64 %a) 55 56 %a1 = add i64 %a, 25 57 %cmp1 = icmp ne i64 %i.ext, %a1 58 call void @assume2(i64 %i.ext, i64 %a1) 59 60 %a2 = add i64 %a1, 25 61 %cmp2 = icmp ne i64 %i.ext, %a2 62 call void @assume2(i64 %i.ext, i64 %a2) 63 64 %a3 = add i64 %a2, 25 65 %cmp3 = icmp ne i64 %i.ext, %a3 66 call void @assume2(i64 %i.ext, i64 %a3) 67 68 %a4 = add i64 %a3, 25 69 %cmp4 = icmp ne i64 %i.ext, %a4 70 call void @assume2(i64 %i.ext, i64 %a4) 71 72 ret void 73 } 74 75 define available_externally void @assume4(i64 %i.ext, i64 %a) alwaysinline { 76 call void @assume3(i64 %i.ext, i64 %a) 77 78 %a1 = add i64 %a, 125 79 %cmp1 = icmp ne i64 %i.ext, %a1 80 call void @assume3(i64 %i.ext, i64 %a1) 81 82 %a2 = add i64 %a1, 125 83 %cmp2 = icmp ne i64 %i.ext, %a2 84 call void @assume3(i64 %i.ext, i64 %a2) 85 86 %a3 = add i64 %a2, 125 87 %cmp3 = icmp ne i64 %i.ext, %a3 88 call void @assume3(i64 %i.ext, i64 %a3) 89 90 %a4 = add i64 %a3, 125 91 %cmp4 = icmp ne i64 %i.ext, %a4 92 call void @assume3(i64 %i.ext, i64 %a4) 93 94 ret void 95 } 96 97 define available_externally void @assume5(i64 %i.ext, i64 %a) alwaysinline { 98 call void @assume4(i64 %i.ext, i64 %a) 99 100 %a1 = add i64 %a, 625 101 %cmp1 = icmp ne i64 %i.ext, %a1 102 call void @assume4(i64 %i.ext, i64 %a1) 103 104 %a2 = add i64 %a1, 625 105 %cmp2 = icmp ne i64 %i.ext, %a2 106 call void @assume4(i64 %i.ext, i64 %a2) 107 108 %a3 = add i64 %a2, 625 109 %cmp3 = icmp ne i64 %i.ext, %a3 110 call void @assume4(i64 %i.ext, i64 %a3) 111 112 %a4 = add i64 %a3, 625 113 %cmp4 = icmp ne i64 %i.ext, %a4 114 call void @assume4(i64 %i.ext, i64 %a4) 115 116 ret void 117 } 118 119 define void @fn(i32 %init) { 120 entry: 121 br label %loop 122 123 loop: 124 %i = phi i32 [%init, %entry], [%next, %loop] 125 call void @body(i32 %i) 126 127 %i.ext = zext i32 %i to i64 128 129 call void @assume5(i64 %i.ext, i64 500000000) 130 131 %i.next = add i64 %i.ext, 1 132 %next = trunc i64 %i.next to i32 133 %done = icmp eq i32 %i, 500000000 134 135 br i1 %done, label %exit, label %loop 136 137 exit: 138 ret void 139 }