1 ; RUN: opt < %s -S -basicaa -licm | FileCheck %s 2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s 3 4 ; Check that we can hoist unordered loads 5 define i32 @test1(i32* nocapture %y) nounwind uwtable ssp { 6 entry: 7 br label %loop 8 9 loop: 10 %i = phi i32 [ %inc, %loop ], [ 0, %entry ] 11 %val = load atomic i32, i32* %y unordered, align 4 12 %inc = add nsw i32 %i, 1 13 %exitcond = icmp eq i32 %inc, %val 14 br i1 %exitcond, label %end, label %loop 15 16 end: 17 ret i32 %val 18 ; CHECK-LABEL: define i32 @test1( 19 ; CHECK: load atomic 20 ; CHECK-NEXT: br label %loop 21 } 22 23 ; Check that we don't sink/hoist monotonic loads 24 ; (Strictly speaking, it's not forbidden, but it's supposed to be possible to 25 ; use monotonic for spinlock-like constructs.) 26 define i32 @test2(i32* nocapture %y) nounwind uwtable ssp { 27 entry: 28 br label %loop 29 30 loop: 31 %val = load atomic i32, i32* %y monotonic, align 4 32 %exitcond = icmp ne i32 %val, 0 33 br i1 %exitcond, label %end, label %loop 34 35 end: 36 ret i32 %val 37 ; CHECK-LABEL: define i32 @test2( 38 ; CHECK: load atomic 39 ; CHECK-NEXT: %exitcond = icmp ne 40 ; CHECK-NEXT: br i1 %exitcond, label %end, label %loop 41 } 42 43 ; Check that we hoist unordered around monotonic. 44 ; (The noalias shouldn't be necessary in theory, but LICM isn't quite that 45 ; smart yet.) 46 define i32 @test3(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 47 entry: 48 br label %loop 49 50 loop: 51 %vala = load atomic i32, i32* %y monotonic, align 4 52 %valb = load atomic i32, i32* %x unordered, align 4 53 %exitcond = icmp ne i32 %vala, %valb 54 br i1 %exitcond, label %end, label %loop 55 56 end: 57 ret i32 %vala 58 ; CHECK-LABEL: define i32 @test3( 59 ; CHECK: load atomic i32, i32* %x unordered 60 ; CHECK-NEXT: br label %loop 61 } 62 63 ; We can sink an unordered store 64 define i32 @test4(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 65 entry: 66 br label %loop 67 68 loop: 69 %vala = load atomic i32, i32* %y monotonic, align 4 70 store atomic i32 %vala, i32* %x unordered, align 4 71 %exitcond = icmp ne i32 %vala, 0 72 br i1 %exitcond, label %end, label %loop 73 74 end: 75 ret i32 %vala 76 ; CHECK-LABEL: define i32 @test4( 77 ; CHECK-LABEL: loop: 78 ; CHECK: load atomic i32, i32* %y monotonic 79 ; CHECK-NOT: store 80 ; CHECK-LABEL: end: 81 ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %vala 82 ; CHECK: store atomic i32 %[[LCSSAPHI]], i32* %x unordered, align 4 83 } 84 85 ; We currently don't handle ordered atomics. 86 define i32 @test5(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 87 entry: 88 br label %loop 89 90 loop: 91 %vala = load atomic i32, i32* %y monotonic, align 4 92 store atomic i32 %vala, i32* %x release, align 4 93 %exitcond = icmp ne i32 %vala, 0 94 br i1 %exitcond, label %end, label %loop 95 96 end: 97 ret i32 %vala 98 ; CHECK-LABEL: define i32 @test5( 99 ; CHECK: load atomic i32, i32* %y monotonic 100 ; CHECK-NEXT: store atomic 101 } 102 103 ; We currently don't touch volatiles 104 define i32 @test6(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 105 entry: 106 br label %loop 107 108 loop: 109 %vala = load atomic i32, i32* %y monotonic, align 4 110 store volatile i32 %vala, i32* %x, align 4 111 %exitcond = icmp ne i32 %vala, 0 112 br i1 %exitcond, label %end, label %loop 113 114 end: 115 ret i32 %vala 116 ; CHECK-LABEL: define i32 @test6( 117 ; CHECK: load atomic i32, i32* %y monotonic 118 ; CHECK-NEXT: store volatile 119 } 120 121 ; We currently don't touch volatiles 122 define i32 @test6b(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 123 entry: 124 br label %loop 125 126 loop: 127 %vala = load atomic i32, i32* %y monotonic, align 4 128 store atomic volatile i32 %vala, i32* %x unordered, align 4 129 %exitcond = icmp ne i32 %vala, 0 130 br i1 %exitcond, label %end, label %loop 131 132 end: 133 ret i32 %vala 134 ; CHECK-LABEL: define i32 @test6b( 135 ; CHECK: load atomic i32, i32* %y monotonic 136 ; CHECK-NEXT: store atomic volatile 137 } 138 139 ; Mixing unorder atomics and normal loads/stores is 140 ; current unimplemented 141 define i32 @test7(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 142 entry: 143 br label %loop 144 145 loop: 146 store i32 5, i32* %x 147 %vala = load atomic i32, i32* %y monotonic, align 4 148 store atomic i32 %vala, i32* %x unordered, align 4 149 %exitcond = icmp ne i32 %vala, 0 150 br i1 %exitcond, label %end, label %loop 151 152 end: 153 ret i32 %vala 154 ; CHECK-LABEL: define i32 @test7( 155 ; CHECK: store i32 5, i32* %x 156 ; CHECK-NEXT: load atomic i32, i32* %y 157 ; CHECK-NEXT: store atomic i32 158 } 159 160 ; Three provably noalias locations - we can sink normal and unordered, but 161 ; not monotonic 162 define i32 @test7b(i32* nocapture noalias %x, i32* nocapture %y, i32* noalias nocapture %z) nounwind uwtable ssp { 163 entry: 164 br label %loop 165 166 loop: 167 store i32 5, i32* %x 168 %vala = load atomic i32, i32* %y monotonic, align 4 169 store atomic i32 %vala, i32* %z unordered, align 4 170 %exitcond = icmp ne i32 %vala, 0 171 br i1 %exitcond, label %end, label %loop 172 173 end: 174 ret i32 %vala 175 ; CHECK-LABEL: define i32 @test7b( 176 ; CHECK: load atomic i32, i32* %y monotonic 177 178 ; CHECK-LABEL: end: 179 ; CHECK: store i32 5, i32* %x 180 ; CHECK: store atomic i32 %{{.+}}, i32* %z unordered, align 4 181 } 182 183 184 define i32 @test8(i32* nocapture noalias %x, i32* nocapture %y) { 185 entry: 186 br label %loop 187 188 loop: 189 %vala = load atomic i32, i32* %y monotonic, align 4 190 store atomic i32 %vala, i32* %x unordered, align 4 191 fence release 192 %exitcond = icmp ne i32 %vala, 0 193 br i1 %exitcond, label %end, label %loop 194 195 end: 196 ret i32 %vala 197 ; CHECK-LABEL: define i32 @test8( 198 ; CHECK-LABEL: loop: 199 ; CHECK: load atomic i32, i32* %y monotonic 200 ; CHECK-NEXT: store atomic 201 ; CHECK-NEXT: fence 202 } 203 204 ; Exact semantics of monotonic accesses are a bit vague in the C++ spec, 205 ; for the moment, be conservative and don't touch them. 206 define i32 @test9(i32* nocapture noalias %x, i32* nocapture %y) { 207 entry: 208 br label %loop 209 210 loop: 211 %vala = load atomic i32, i32* %y monotonic, align 4 212 store atomic i32 %vala, i32* %x monotonic, align 4 213 %exitcond = icmp ne i32 %vala, 0 214 br i1 %exitcond, label %end, label %loop 215 216 end: 217 ret i32 %vala 218 ; CHECK-LABEL: define i32 @test9( 219 ; CHECK-LABEL: loop: 220 ; CHECK: load atomic i32, i32* %y monotonic 221 ; CHECK-NEXT: store atomic i32 %vala, i32* %x monotonic, align 4 222 } 223