222 lines · plain
1; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s2 3; Check that we can hoist unordered loads4define i32 @test1(ptr nocapture %y) nounwind uwtable ssp {5entry:6 br label %loop7 8loop:9 %i = phi i32 [ %inc, %loop ], [ 0, %entry ]10 %val = load atomic i32, ptr %y unordered, align 411 %inc = add nsw i32 %i, 112 %exitcond = icmp eq i32 %inc, %val13 br i1 %exitcond, label %end, label %loop14 15end:16 ret i32 %val17; CHECK-LABEL: define i32 @test1(18; CHECK: load atomic19; CHECK-NEXT: br label %loop20}21 22; Check that we don't sink/hoist monotonic loads23; (Strictly speaking, it's not forbidden, but it's supposed to be possible to24; use monotonic for spinlock-like constructs.)25define i32 @test2(ptr nocapture %y) nounwind uwtable ssp {26entry:27 br label %loop28 29loop:30 %val = load atomic i32, ptr %y monotonic, align 431 %exitcond = icmp ne i32 %val, 032 br i1 %exitcond, label %end, label %loop33 34end:35 ret i32 %val36; CHECK-LABEL: define i32 @test2(37; CHECK: load atomic38; CHECK-NEXT: %exitcond = icmp ne39; CHECK-NEXT: br i1 %exitcond, label %end, label %loop40}41 42; Check that we hoist unordered around monotonic.43; (The noalias shouldn't be necessary in theory, but LICM isn't quite that44; smart yet.)45define i32 @test3(ptr nocapture noalias %x, ptr nocapture %y) nounwind uwtable ssp {46entry:47 br label %loop48 49loop:50 %vala = load atomic i32, ptr %y monotonic, align 451 %valb = load atomic i32, ptr %x unordered, align 452 %exitcond = icmp ne i32 %vala, %valb53 br i1 %exitcond, label %end, label %loop54 55end:56 ret i32 %vala57; CHECK-LABEL: define i32 @test3(58; CHECK: load atomic i32, ptr %x unordered59; CHECK-NEXT: br label %loop60}61 62; We can sink an unordered store63define i32 @test4(ptr nocapture noalias %x, ptr nocapture %y) nounwind uwtable ssp {64entry:65 br label %loop66 67loop:68 %vala = load atomic i32, ptr %y monotonic, align 469 store atomic i32 %vala, ptr %x unordered, align 470 %exitcond = icmp ne i32 %vala, 071 br i1 %exitcond, label %end, label %loop72 73end:74 ret i32 %vala75; CHECK-LABEL: define i32 @test4(76; CHECK-LABEL: loop:77; CHECK: load atomic i32, ptr %y monotonic78; CHECK-NOT: store79; CHECK-LABEL: end:80; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %vala81; CHECK: store atomic i32 %[[LCSSAPHI]], ptr %x unordered, align 482}83 84; We currently don't handle ordered atomics.85define i32 @test5(ptr nocapture noalias %x, ptr nocapture %y) nounwind uwtable ssp {86entry:87 br label %loop88 89loop:90 %vala = load atomic i32, ptr %y monotonic, align 491 store atomic i32 %vala, ptr %x release, align 492 %exitcond = icmp ne i32 %vala, 093 br i1 %exitcond, label %end, label %loop94 95end:96 ret i32 %vala97; CHECK-LABEL: define i32 @test5(98; CHECK: load atomic i32, ptr %y monotonic99; CHECK-NEXT: store atomic100}101 102; We currently don't touch volatiles103define i32 @test6(ptr nocapture noalias %x, ptr nocapture %y) nounwind uwtable ssp {104entry:105 br label %loop106 107loop:108 %vala = load atomic i32, ptr %y monotonic, align 4109 store volatile i32 %vala, ptr %x, align 4110 %exitcond = icmp ne i32 %vala, 0111 br i1 %exitcond, label %end, label %loop112 113end:114 ret i32 %vala115; CHECK-LABEL: define i32 @test6(116; CHECK: load atomic i32, ptr %y monotonic117; CHECK-NEXT: store volatile118}119 120; We currently don't touch volatiles121define i32 @test6b(ptr nocapture noalias %x, ptr nocapture %y) nounwind uwtable ssp {122entry:123 br label %loop124 125loop:126 %vala = load atomic i32, ptr %y monotonic, align 4127 store atomic volatile i32 %vala, ptr %x unordered, align 4128 %exitcond = icmp ne i32 %vala, 0129 br i1 %exitcond, label %end, label %loop130 131end:132 ret i32 %vala133; CHECK-LABEL: define i32 @test6b(134; CHECK: load atomic i32, ptr %y monotonic135; CHECK-NEXT: store atomic volatile136}137 138; Mixing unorder atomics and normal loads/stores is139; current unimplemented140define i32 @test7(ptr nocapture noalias %x, ptr nocapture %y) nounwind uwtable ssp {141entry:142 br label %loop143 144loop:145 store i32 5, ptr %x146 %vala = load atomic i32, ptr %y monotonic, align 4147 store atomic i32 %vala, ptr %x unordered, align 4148 %exitcond = icmp ne i32 %vala, 0149 br i1 %exitcond, label %end, label %loop150 151end:152 ret i32 %vala153; CHECK-LABEL: define i32 @test7(154; CHECK: store i32 5, ptr %x155; CHECK-NEXT: load atomic i32, ptr %y156; CHECK-NEXT: store atomic i32157}158 159; Three provably noalias locations - we can sink normal and unordered, but160; not monotonic161define i32 @test7b(ptr nocapture noalias %x, ptr nocapture %y, ptr noalias nocapture %z) nounwind uwtable ssp {162entry:163 br label %loop164 165loop:166 store i32 5, ptr %x167 %vala = load atomic i32, ptr %y monotonic, align 4168 store atomic i32 %vala, ptr %z unordered, align 4169 %exitcond = icmp ne i32 %vala, 0170 br i1 %exitcond, label %end, label %loop171 172end:173 ret i32 %vala174; CHECK-LABEL: define i32 @test7b(175; CHECK-LABEL: loop:176; CHECK: load atomic i32, ptr %y monotonic177; CHECK-LABEL: end:178; CHECK: store i32 5, ptr %x179; CHECK: store atomic i32 %{{.+}}, ptr %z unordered, align 4180}181 182 183define i32 @test8(ptr nocapture noalias %x, ptr nocapture %y) {184entry:185 br label %loop186 187loop:188 %vala = load atomic i32, ptr %y monotonic, align 4189 store atomic i32 %vala, ptr %x unordered, align 4190 fence release191 %exitcond = icmp ne i32 %vala, 0192 br i1 %exitcond, label %end, label %loop193 194end:195 ret i32 %vala196; CHECK-LABEL: define i32 @test8(197; CHECK-LABEL: loop:198; CHECK: load atomic i32, ptr %y monotonic199; CHECK-NEXT: store atomic200; CHECK-NEXT: fence201}202 203; Exact semantics of monotonic accesses are a bit vague in the C++ spec,204; for the moment, be conservative and don't touch them.205define i32 @test9(ptr nocapture noalias %x, ptr nocapture %y) {206entry:207 br label %loop208 209loop:210 %vala = load atomic i32, ptr %y monotonic, align 4211 store atomic i32 %vala, ptr %x monotonic, align 4212 %exitcond = icmp ne i32 %vala, 0213 br i1 %exitcond, label %end, label %loop214 215end:216 ret i32 %vala217; CHECK-LABEL: define i32 @test9(218; CHECK-LABEL: loop:219; CHECK: load atomic i32, ptr %y monotonic220; CHECK-NEXT: store atomic i32 %vala, ptr %x monotonic, align 4221}222