1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -early-cse < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; NOTE: This file is testing the current implementation. Some of 3*9880d681SAndroid Build Coastguard Worker; the transforms used as negative tests below would be legal, but 4*9880d681SAndroid Build Coastguard Worker; only if reached through a chain of logic which EarlyCSE is incapable 5*9880d681SAndroid Build Coastguard Worker; of performing. To say it differently, this file tests a conservative 6*9880d681SAndroid Build Coastguard Worker; version of the memory model. If we want to extend EarlyCSE to be more 7*9880d681SAndroid Build Coastguard Worker; aggressive in the future, we may need to relax some of the negative tests. 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; We can value forward across the fence since we can (semantically) 10*9880d681SAndroid Build Coastguard Worker; reorder the following load before the fence. 11*9880d681SAndroid Build Coastguard Workerdefine i32 @test(i32* %addr.i) { 12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test 13*9880d681SAndroid Build Coastguard Worker; CHECK: store 14*9880d681SAndroid Build Coastguard Worker; CHECK: fence 15*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 16*9880d681SAndroid Build Coastguard Worker; CHECK: ret 17*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %addr.i, align 4 18*9880d681SAndroid Build Coastguard Worker fence release 19*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %addr.i, align 4 20*9880d681SAndroid Build Coastguard Worker ret i32 %a 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; Same as above 24*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32* noalias %addr.i, i32* noalias %otheraddr) { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2 26*9880d681SAndroid Build Coastguard Worker; CHECK: load 27*9880d681SAndroid Build Coastguard Worker; CHECK: fence 28*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 29*9880d681SAndroid Build Coastguard Worker; CHECK: ret 30*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %addr.i, align 4 31*9880d681SAndroid Build Coastguard Worker fence release 32*9880d681SAndroid Build Coastguard Worker %a2 = load i32, i32* %addr.i, align 4 33*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %a2 34*9880d681SAndroid Build Coastguard Worker ret i32 %a 35*9880d681SAndroid Build Coastguard Worker} 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; We can not value forward across an acquire barrier since we might 38*9880d681SAndroid Build Coastguard Worker; be syncronizing with another thread storing to the same variable 39*9880d681SAndroid Build Coastguard Worker; followed by a release fence. If this thread observed the release 40*9880d681SAndroid Build Coastguard Worker; had happened, we must present a consistent view of memory at the 41*9880d681SAndroid Build Coastguard Worker; fence. Note that it would be legal to reorder '%a' after the fence 42*9880d681SAndroid Build Coastguard Worker; and then remove '%a2'. The current implementation doesn't know how 43*9880d681SAndroid Build Coastguard Worker; to do this, but if it learned, this test will need revised. 44*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32* noalias %addr.i, i32* noalias %otheraddr) { 45*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3 46*9880d681SAndroid Build Coastguard Worker; CHECK: load 47*9880d681SAndroid Build Coastguard Worker; CHECK: fence 48*9880d681SAndroid Build Coastguard Worker; CHECK: load 49*9880d681SAndroid Build Coastguard Worker; CHECK: sub 50*9880d681SAndroid Build Coastguard Worker; CHECK: ret 51*9880d681SAndroid Build Coastguard Worker %a = load i32, i32* %addr.i, align 4 52*9880d681SAndroid Build Coastguard Worker fence acquire 53*9880d681SAndroid Build Coastguard Worker %a2 = load i32, i32* %addr.i, align 4 54*9880d681SAndroid Build Coastguard Worker %res = sub i32 %a, %a2 55*9880d681SAndroid Build Coastguard Worker ret i32 %res 56*9880d681SAndroid Build Coastguard Worker} 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; We can not dead store eliminate accross the fence. We could in 59*9880d681SAndroid Build Coastguard Worker; principal reorder the second store above the fence and then DSE either 60*9880d681SAndroid Build Coastguard Worker; store, but this is beyond the simple last-store DSE which EarlyCSE 61*9880d681SAndroid Build Coastguard Worker; implements. 62*9880d681SAndroid Build Coastguard Workerdefine void @test4(i32* %addr.i) { 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4 64*9880d681SAndroid Build Coastguard Worker; CHECK: store 65*9880d681SAndroid Build Coastguard Worker; CHECK: fence 66*9880d681SAndroid Build Coastguard Worker; CHECK: store 67*9880d681SAndroid Build Coastguard Worker; CHECK: ret 68*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %addr.i, align 4 69*9880d681SAndroid Build Coastguard Worker fence release 70*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %addr.i, align 4 71*9880d681SAndroid Build Coastguard Worker ret void 72*9880d681SAndroid Build Coastguard Worker} 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker; We *could* DSE across this fence, but don't. No other thread can 75*9880d681SAndroid Build Coastguard Worker; observe the order of the acquire fence and the store. 76*9880d681SAndroid Build Coastguard Workerdefine void @test5(i32* %addr.i) { 77*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5 78*9880d681SAndroid Build Coastguard Worker; CHECK: store 79*9880d681SAndroid Build Coastguard Worker; CHECK: fence 80*9880d681SAndroid Build Coastguard Worker; CHECK: store 81*9880d681SAndroid Build Coastguard Worker; CHECK: ret 82*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %addr.i, align 4 83*9880d681SAndroid Build Coastguard Worker fence acquire 84*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %addr.i, align 4 85*9880d681SAndroid Build Coastguard Worker ret void 86*9880d681SAndroid Build Coastguard Worker} 87