brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · d4f62d1 Raw
460 lines · plain
1; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<target-ir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s2 3define void @test(ptr %loc) {4; CHECK-LABEL: @test5; CHECK-LABEL: entry:6; CHECK: store i32 0, ptr %loc7; CHECK-LABEL: loop:8entry:9  br label %loop10 11loop:12  %iv = phi i32 [0, %entry], [%iv.next, %loop]13  store i32 0, ptr %loc14  %iv.next = add i32 %iv, 115  %cmp = icmp slt i32 %iv, 20016  br i1 %cmp, label %loop, label %exit17 18exit:19  ret void20}21 22define void @test_multiexit(ptr %loc, i1 %earlycnd) {23; CHECK-LABEL: @test_multiexit24; CHECK-LABEL: entry:25; CHECK: store i32 0, ptr %loc26; CHECK-LABEL: loop:27entry:28  br label %loop29 30loop:31  %iv = phi i32 [0, %entry], [%iv.next, %backedge]32  store i32 0, ptr %loc33  %iv.next = add i32 %iv, 134  br i1 %earlycnd, label %exit1, label %backedge35  36backedge:37  %cmp = icmp slt i32 %iv, 20038  br i1 %cmp, label %loop, label %exit239 40exit1:41  ret void42exit2:43  ret void44}45 46define ptr @false_negative_2use(ptr %loc) {47; CHECK-LABEL: @false_negative_2use48; CHECK-LABEL: entry:49; CHECK: store i32 0, ptr %loc50; CHECK-LABEL: loop:51entry:52  br label %loop53 54loop:55  %iv = phi i32 [0, %entry], [%iv.next, %loop]56  store i32 0, ptr %loc57  %iv.next = add i32 %iv, 158  %cmp = icmp slt i32 %iv, 20059  br i1 %cmp, label %loop, label %exit60 61exit:62  ret ptr %loc63}64 65define void @neg_lv_value(ptr %loc) {66; CHECK-LABEL: @neg_lv_value67; CHECK-LABEL: exit:68; CHECK: store i32 %iv.lcssa, ptr %loc69entry:70  br label %loop71 72loop:73  %iv = phi i32 [0, %entry], [%iv.next, %loop]74  store i32 %iv, ptr %loc75  %iv.next = add i32 %iv, 176  %cmp = icmp slt i32 %iv, 20077  br i1 %cmp, label %loop, label %exit78 79exit:80  ret void81}82 83define void @neg_lv_addr(ptr %loc) {84; CHECK-LABEL: @neg_lv_addr85; CHECK-LABEL: loop:86; CHECK: store i32 0, ptr %p87; CHECK-LABEL: exit:88entry:89  br label %loop90 91loop:92  %iv = phi i32 [0, %entry], [%iv.next, %loop]93  %p = getelementptr i32, ptr %loc, i32 %iv94  store i32 0, ptr %p95  %iv.next = add i32 %iv, 196  %cmp = icmp slt i32 %iv, 20097  br i1 %cmp, label %loop, label %exit98 99exit:100  ret void101}102 103define void @neg_mod(ptr %loc) {104; CHECK-LABEL: @neg_mod105; CHECK-LABEL: exit:106; CHECK: store i32 %iv.lcssa, ptr %loc107entry:108  br label %loop109 110loop:111  %iv = phi i32 [0, %entry], [%iv.next, %loop]112  store i32 0, ptr %loc113  store i32 %iv, ptr %loc114  %iv.next = add i32 %iv, 1115  %cmp = icmp slt i32 %iv, 200116  br i1 %cmp, label %loop, label %exit117 118exit:119  ret void120}121 122; Hoisting the store is actually valid here, as it dominates the load.123define void @neg_ref(ptr %loc) {124; CHECK-LABEL: @neg_ref125; CHECK-LABEL: exit1:126; CHECK: store i32 0, ptr %loc127; CHECK-LABEL: exit2:128; CHECK: store i32 0, ptr %loc129entry:130  br label %loop131 132loop:133  %iv = phi i32 [0, %entry], [%iv.next, %backedge]134  store i32 0, ptr %loc135  %v = load i32, ptr %loc136  %earlycnd = icmp eq i32 %v, 198137  br i1 %earlycnd, label %exit1, label %backedge138  139backedge:140  %iv.next = add i32 %iv, 1141  %cmp = icmp slt i32 %iv, 200142  br i1 %cmp, label %loop, label %exit2143 144exit1:145  ret void146exit2:147  ret void148}149 150; Hoisting the store here leads to a miscompile.151define void @neg_ref2(ptr %loc) {152; CHECK-LABEL: @neg_ref2153; CHECK-LABEL: exit1:154; CHECK: store i32 0, ptr %loc155; CHECK-LABEL: exit2:156; CHECK: store i32 0, ptr %loc157entry:158  store i32 198, ptr %loc159  br label %loop160 161loop:162  %iv = phi i32 [0, %entry], [%iv.next, %backedge]163  %v = load i32, ptr %loc164  store i32 0, ptr %loc165  %earlycnd = icmp eq i32 %v, 198166  br i1 %earlycnd, label %exit1, label %backedge167  168backedge:169  %iv.next = add i32 %iv, 1170  %cmp = icmp slt i32 %iv, 200171  br i1 %cmp, label %loop, label %exit2172 173exit1:174  ret void175exit2:176  ret void177}178 179declare void @modref()180 181define void @neg_modref(ptr %loc) {182; CHECK-LABEL: @neg_modref183; CHECK-LABEL: loop:184; CHECK: store i32 0, ptr %loc185; CHECK-LABEL: exit:186entry:187  br label %loop188 189loop:190  %iv = phi i32 [0, %entry], [%iv.next, %loop]191  store i32 0, ptr %loc192  call void @modref()193  %iv.next = add i32 %iv, 1194  %cmp = icmp slt i32 %iv, 200195  br i1 %cmp, label %loop, label %exit196 197exit:198  ret void199}200 201define void @neg_fence(ptr %loc) {202; CHECK-LABEL: @neg_fence203; CHECK-LABEL: loop:204; CHECK: store i32 0, ptr %loc205; CHECK-LABEL: exit:206entry:207  br label %loop208 209loop:210  %iv = phi i32 [0, %entry], [%iv.next, %loop]211  store i32 0, ptr %loc212  fence seq_cst213  %iv.next = add i32 %iv, 1214  %cmp = icmp slt i32 %iv, 200215  br i1 %cmp, label %loop, label %exit216 217exit:218  ret void219}220 221define void @neg_volatile(ptr %loc) {222; CHECK-LABEL: @neg_volatile223; CHECK-LABEL: loop:224; CHECK: store volatile i32 0, ptr %loc225; CHECK-LABEL: exit:226entry:227  br label %loop228 229loop:230  %iv = phi i32 [0, %entry], [%iv.next, %loop]231  store volatile i32 0, ptr %loc232  %iv.next = add i32 %iv, 1233  %cmp = icmp slt i32 %iv, 200234  br i1 %cmp, label %loop, label %exit235 236exit:237  ret void238}239 240define void @neg_release(ptr %loc) {241; CHECK-LABEL: @neg_release242; CHECK-LABEL: loop:243; CHECK: store atomic i32 0, ptr %loc release, align 4244; CHECK-LABEL: exit:245entry:246  br label %loop247 248loop:249  %iv = phi i32 [0, %entry], [%iv.next, %loop]250  store atomic i32 0, ptr %loc release, align 4251  %iv.next = add i32 %iv, 1252  %cmp = icmp slt i32 %iv, 200253  br i1 %cmp, label %loop, label %exit254 255exit:256  ret void257}258 259define void @neg_seq_cst(ptr %loc) {260; CHECK-LABEL: @neg_seq_cst261; CHECK-LABEL: loop:262; CHECK: store atomic i32 0, ptr %loc seq_cst, align 4263; CHECK-LABEL: exit:264entry:265  br label %loop266 267loop:268  %iv = phi i32 [0, %entry], [%iv.next, %loop]269  store atomic i32 0, ptr %loc seq_cst, align 4270  %iv.next = add i32 %iv, 1271  %cmp = icmp slt i32 %iv, 200272  br i1 %cmp, label %loop, label %exit273 274exit:275  ret void276}277 278declare void @maythrow() inaccessiblememonly279 280define void @neg_early_exit(ptr %loc) {281; CHECK-LABEL: @neg_early_exit282; CHECK-LABEL: body:283; CHECK: store i32 0, ptr %loc284; CHECK-LABEL: exit:285entry:286  br label %loop287 288loop:289  %iv = phi i32 [0, %entry], [%iv.next, %body]290  %is_null = icmp eq ptr %loc, null291  br i1 %is_null, label %exit, label %body292body:293  call void @maythrow()294  store i32 0, ptr %loc295  %iv.next = add i32 %iv, 1296  %cmp = icmp slt i32 %iv, 200297  br i1 %cmp, label %loop, label %exit298 299exit:300  ret void301}302 303define void @neg_early_throw(ptr %loc) {304; CHECK-LABEL: @neg_early_throw305; CHECK-LABEL: loop:306; CHECK: store i32 0, ptr %loc307; CHECK-LABEL: exit:308entry:309  br label %loop310 311loop:312  %iv = phi i32 [0, %entry], [%iv.next, %loop]313  call void @maythrow()314  store i32 0, ptr %loc315  %iv.next = add i32 %iv, 1316  %cmp = icmp slt i32 %iv, 200317  br i1 %cmp, label %loop, label %exit318 319exit:320  ret void321}322 323define void @test_late_throw(ptr %loc) {324; CHECK-LABEL: @test_late_throw325; CHECK-LABEL: entry:326; CHECK: store i32 0, ptr %loc327; CHECK-LABEL: loop:328entry:329  br label %loop330 331loop:332  %iv = phi i32 [0, %entry], [%iv.next, %loop]333  store i32 0, ptr %loc334  call void @maythrow()335  %iv.next = add i32 %iv, 1336  %cmp = icmp slt i32 %iv, 200337  br i1 %cmp, label %loop, label %exit338 339exit:340  ret void341}342 343; TODO: could validly hoist the store here since we know what value344; the load must observe.345define i32 @test_dominated_read(ptr %loc) {346; CHECK-LABEL: @test_dominated_read347; CHECK-LABEL: entry:348; CHECK: store i32 0, ptr %loc349; CHECK-LABEL: loop:350entry:351  br label %loop352 353loop:354  %iv = phi i32 [0, %entry], [%iv.next, %loop]355  store i32 0, ptr %loc356  %reload = load i32, ptr %loc357  %iv.next = add i32 %iv, 1358  %cmp = icmp slt i32 %iv, 200359  br i1 %cmp, label %loop, label %exit360 361exit:362  ret i32 %reload363}364 365; TODO: could validly hoist the store since we already hoisted the load and366; it's no longer in the loop.367define i32 @test_dominating_read(ptr %loc) {368; CHECK-LABEL: @test_dominating_read369; CHECK-LABEL: exit:370; CHECK: store i32 0, ptr %loc371entry:372  br label %loop373 374loop:375  %iv = phi i32 [0, %entry], [%iv.next, %loop]376  %reload = load i32, ptr %loc377  store i32 0, ptr %loc378  %iv.next = add i32 %iv, 1379  %cmp = icmp slt i32 %iv, 200380  br i1 %cmp, label %loop, label %exit381 382exit:383  ret i32 %reload384}385 386declare void @readonly() readonly387 388; TODO: can legally hoist since value read by call is known389define void @test_dominated_readonly(ptr %loc) {390; CHECK-LABEL: @test_dominated_readonly391; CHECK-LABEL: loop:392; CHECK: store i32 0, ptr %loc393; CHECK-LABEL: exit:394entry:395  br label %loop396 397loop:398  %iv = phi i32 [0, %entry], [%iv.next, %loop]399  store i32 0, ptr %loc400  call void @readonly()401  %iv.next = add i32 %iv, 1402  %cmp = icmp slt i32 %iv, 200403  br i1 %cmp, label %loop, label %exit404 405exit:406  ret void407}408 409; While technically possible to hoist the store to %loc, this runs across410; a funemental limitation of alias sets since both stores and the call are411; within the same alias set and we can't distinguish them cheaply.412define void @test_aliasset_fn(ptr %loc, ptr %loc2) {413; CHECK-LABEL: @test_aliasset_fn414; CHECK-LABEL: loop:415; CHECK: store i32 0, ptr %loc416; CHECK-LABEL: exit:417entry:418  br label %loop419 420loop:421  %iv = phi i32 [0, %entry], [%iv.next, %loop]422  store i32 0, ptr %loc423  call void @readonly()424  store i32 %iv, ptr %loc2425  %iv.next = add i32 %iv, 1426  %cmp = icmp slt i32 %iv, 200427  br i1 %cmp, label %loop, label %exit428 429exit:430  ret void431}432 433 434; If we can't tell if the value is read before the write, we can't hoist the435; write over the potential read (since we don't know the value read)436define void @neg_may_read(ptr %loc, i1 %maybe) {437; CHECK-LABEL: @neg_may_read438; CHECK-LABEL: loop:439; CHECK: store i32 0, ptr %loc440; CHECK-LABEL: exit:441entry:442  br label %loop443 444loop:445  %iv = phi i32 [0, %entry], [%iv.next, %merge]446  ;; maybe is a placeholder for an unanalyzable condition447  br i1 %maybe, label %taken, label %merge448taken:449  call void @readonly()450  br label %merge451merge:452  store i32 0, ptr %loc453  %iv.next = add i32 %iv, 1454  %cmp = icmp slt i32 %iv, 200455  br i1 %cmp, label %loop, label %exit456 457exit:458  ret void459}460