1*9880d681SAndroid Build Coastguard Worker; Tests that check our handling of volatile instructions encountered 2*9880d681SAndroid Build Coastguard Worker; when scanning for dependencies 3*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -gvn -S < %s | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; Check that we can bypass a volatile load when searching 6*9880d681SAndroid Build Coastguard Worker; for dependencies of a non-volatile load 7*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32* nocapture %p, i32* nocapture %q) { 8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1 9*9880d681SAndroid Build Coastguard Worker; CHECK: %0 = load volatile i32, i32* %q 10*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 0 11*9880d681SAndroid Build Coastguard Workerentry: 12*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* %p 13*9880d681SAndroid Build Coastguard Worker load volatile i32, i32* %q 14*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p 15*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 16*9880d681SAndroid Build Coastguard Worker ret i32 %add 17*9880d681SAndroid Build Coastguard Worker} 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker; We can not value forward if the query instruction is 20*9880d681SAndroid Build Coastguard Worker; volatile, this would be (in effect) removing the volatile load 21*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32* nocapture %p, i32* nocapture %q) { 22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test2 23*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load i32, i32* %p 24*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %y = load volatile i32, i32* %p 25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = sub i32 %y, %x 26*9880d681SAndroid Build Coastguard Workerentry: 27*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* %p 28*9880d681SAndroid Build Coastguard Worker %y = load volatile i32, i32* %p 29*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 30*9880d681SAndroid Build Coastguard Worker ret i32 %add 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; If the query instruction is itself volatile, we *cannot* 34*9880d681SAndroid Build Coastguard Worker; reorder it even if p and q are noalias 35*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32* noalias nocapture %p, i32* noalias nocapture %q) { 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3 37*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load i32, i32* %p 38*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %0 = load volatile i32, i32* %q 39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %y = load volatile i32, i32* %p 40*9880d681SAndroid Build Coastguard Workerentry: 41*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* %p 42*9880d681SAndroid Build Coastguard Worker load volatile i32, i32* %q 43*9880d681SAndroid Build Coastguard Worker %y = load volatile i32, i32* %p 44*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 45*9880d681SAndroid Build Coastguard Worker ret i32 %add 46*9880d681SAndroid Build Coastguard Worker} 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker; If an encountered instruction is both volatile and ordered, 49*9880d681SAndroid Build Coastguard Worker; we need to use the strictest ordering of either. In this 50*9880d681SAndroid Build Coastguard Worker; case, the ordering prevents forwarding. 51*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32* noalias nocapture %p, i32* noalias nocapture %q) { 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test4 53*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load i32, i32* %p 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %0 = load atomic volatile i32, i32* %q seq_cst 55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %y = load atomic i32, i32* %p seq_cst 56*9880d681SAndroid Build Coastguard Workerentry: 57*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* %p 58*9880d681SAndroid Build Coastguard Worker load atomic volatile i32, i32* %q seq_cst, align 4 59*9880d681SAndroid Build Coastguard Worker %y = load atomic i32, i32* %p seq_cst, align 4 60*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 61*9880d681SAndroid Build Coastguard Worker ret i32 %add 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker; Value forwarding from a volatile load is perfectly legal 65*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i32* nocapture %p, i32* nocapture %q) { 66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test5 67*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load volatile i32, i32* %p 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 0 69*9880d681SAndroid Build Coastguard Workerentry: 70*9880d681SAndroid Build Coastguard Worker %x = load volatile i32, i32* %p 71*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p 72*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 73*9880d681SAndroid Build Coastguard Worker ret i32 %add 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; Does cross block redundancy elimination work with volatiles? 77*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i32* noalias nocapture %p, i32* noalias nocapture %q) { 78*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test6 79*9880d681SAndroid Build Coastguard Worker; CHECK: %y1 = load i32, i32* %p 80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: header 81*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load volatile i32, i32* %q 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = sub i32 %y1, %x 83*9880d681SAndroid Build Coastguard Workerentry: 84*9880d681SAndroid Build Coastguard Worker %y1 = load i32, i32* %p 85*9880d681SAndroid Build Coastguard Worker call void @use(i32 %y1) 86*9880d681SAndroid Build Coastguard Worker br label %header 87*9880d681SAndroid Build Coastguard Workerheader: 88*9880d681SAndroid Build Coastguard Worker %x = load volatile i32, i32* %q 89*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p 90*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 91*9880d681SAndroid Build Coastguard Worker %cnd = icmp eq i32 %add, 0 92*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %exit, label %header 93*9880d681SAndroid Build Coastguard Workerexit: 94*9880d681SAndroid Build Coastguard Worker ret i32 %add 95*9880d681SAndroid Build Coastguard Worker} 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker; Does cross block PRE work with volatiles? 98*9880d681SAndroid Build Coastguard Workerdefine i32 @test7(i1 %c, i32* noalias nocapture %p, i32* noalias nocapture %q) { 99*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test7 100*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: entry.header_crit_edge: 101*9880d681SAndroid Build Coastguard Worker; CHECK: %y.pre = load i32, i32* %p 102*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: skip: 103*9880d681SAndroid Build Coastguard Worker; CHECK: %y1 = load i32, i32* %p 104*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: header: 105*9880d681SAndroid Build Coastguard Worker; CHECK: %y = phi i32 106*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %x = load volatile i32, i32* %q 107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = sub i32 %y, %x 108*9880d681SAndroid Build Coastguard Workerentry: 109*9880d681SAndroid Build Coastguard Worker br i1 %c, label %header, label %skip 110*9880d681SAndroid Build Coastguard Workerskip: 111*9880d681SAndroid Build Coastguard Worker %y1 = load i32, i32* %p 112*9880d681SAndroid Build Coastguard Worker call void @use(i32 %y1) 113*9880d681SAndroid Build Coastguard Worker br label %header 114*9880d681SAndroid Build Coastguard Workerheader: 115*9880d681SAndroid Build Coastguard Worker %x = load volatile i32, i32* %q 116*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p 117*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 118*9880d681SAndroid Build Coastguard Worker %cnd = icmp eq i32 %add, 0 119*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %exit, label %header 120*9880d681SAndroid Build Coastguard Workerexit: 121*9880d681SAndroid Build Coastguard Worker ret i32 %add 122*9880d681SAndroid Build Coastguard Worker} 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker; Another volatile PRE case - two paths through a loop 125*9880d681SAndroid Build Coastguard Worker; load in preheader, one path read only, one not 126*9880d681SAndroid Build Coastguard Workerdefine i32 @test8(i1 %b, i1 %c, i32* noalias %p, i32* noalias %q) { 127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test8 128*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: entry 129*9880d681SAndroid Build Coastguard Worker; CHECK: %y1 = load i32, i32* %p 130*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: header: 131*9880d681SAndroid Build Coastguard Worker; CHECK: %y = phi i32 132*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %x = load volatile i32, i32* %q 133*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 134*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: skip.header_crit_edge: 135*9880d681SAndroid Build Coastguard Worker; CHECK: %y.pre = load i32, i32* %p 136*9880d681SAndroid Build Coastguard Workerentry: 137*9880d681SAndroid Build Coastguard Worker %y1 = load i32, i32* %p 138*9880d681SAndroid Build Coastguard Worker call void @use(i32 %y1) 139*9880d681SAndroid Build Coastguard Worker br label %header 140*9880d681SAndroid Build Coastguard Workerheader: 141*9880d681SAndroid Build Coastguard Worker %x = load volatile i32, i32* %q 142*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p 143*9880d681SAndroid Build Coastguard Worker call void @use(i32 %y) 144*9880d681SAndroid Build Coastguard Worker br i1 %b, label %skip, label %header 145*9880d681SAndroid Build Coastguard Workerskip: 146*9880d681SAndroid Build Coastguard Worker ; escaping the arguments is explicitly required since we marked 147*9880d681SAndroid Build Coastguard Worker ; them noalias 148*9880d681SAndroid Build Coastguard Worker call void @clobber(i32* %p, i32* %q) 149*9880d681SAndroid Build Coastguard Worker br i1 %c, label %header, label %exit 150*9880d681SAndroid Build Coastguard Workerexit: 151*9880d681SAndroid Build Coastguard Worker %add = sub i32 %y, %x 152*9880d681SAndroid Build Coastguard Worker ret i32 %add 153*9880d681SAndroid Build Coastguard Worker} 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workerdefine i32 @test9(i32* %V) { 156*9880d681SAndroid Build Coastguard Workerentry: 157*9880d681SAndroid Build Coastguard Worker %load = load volatile i32, i32* %V, !range !0 158*9880d681SAndroid Build Coastguard Worker ret i32 %load 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test9 161*9880d681SAndroid Build Coastguard Worker; CHECK: load volatile 162*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerdeclare void @use(i32) readonly 165*9880d681SAndroid Build Coastguard Workerdeclare void @clobber(i32* %p, i32* %q) 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker!0 = !{ i32 0, i32 1 } 168