1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -gvn -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker%struct.A = type { i32 (...)** } 4*9880d681SAndroid Build Coastguard Worker@_ZTV1A = available_externally unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast (i8** @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A3fooEv to i8*)], align 8 5*9880d681SAndroid Build Coastguard Worker@_ZTI1A = external constant i8* 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker@unknownPtr = external global i8 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @simple() { 10*9880d681SAndroid Build Coastguard Workerdefine i8 @simple() { 11*9880d681SAndroid Build Coastguard Workerentry: 12*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 13*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 14*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 17*9880d681SAndroid Build Coastguard Worker %b = load i8, i8* %ptr, !invariant.group !0 18*9880d681SAndroid Build Coastguard Worker %c = load i8, i8* %ptr, !invariant.group !0 19*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42 20*9880d681SAndroid Build Coastguard Worker ret i8 %a 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @optimizable1() { 24*9880d681SAndroid Build Coastguard Workerdefine i8 @optimizable1() { 25*9880d681SAndroid Build Coastguard Workerentry: 26*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 27*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 28*9880d681SAndroid Build Coastguard Worker %ptr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr) 29*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr2); call to use %ptr2 32*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42 33*9880d681SAndroid Build Coastguard Worker ret i8 %a 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @optimizable2() { 37*9880d681SAndroid Build Coastguard Workerdefine i8 @optimizable2() { 38*9880d681SAndroid Build Coastguard Workerentry: 39*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 40*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 41*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker store i8 13, i8* %ptr ; can't use this store with invariant.group 44*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr 45*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %a) ; call to use %a 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 48*9880d681SAndroid Build Coastguard Worker %b = load i8, i8* %ptr, !invariant.group !0 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42 51*9880d681SAndroid Build Coastguard Worker ret i8 %b 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable1() { 55*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable1() { 56*9880d681SAndroid Build Coastguard Workerentry: 57*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 58*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr 59*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 60*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 61*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a 62*9880d681SAndroid Build Coastguard Worker ret i8 %a 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @indirectLoads() { 66*9880d681SAndroid Build Coastguard Workerdefine void @indirectLoads() { 67*9880d681SAndroid Build Coastguard Workerentry: 68*9880d681SAndroid Build Coastguard Worker %a = alloca %struct.A*, align 8 69*9880d681SAndroid Build Coastguard Worker %0 = bitcast %struct.A** %a to i8* 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker %call = call i8* @getPointer(i8* null) 72*9880d681SAndroid Build Coastguard Worker %1 = bitcast i8* %call to %struct.A* 73*9880d681SAndroid Build Coastguard Worker call void @_ZN1AC1Ev(%struct.A* %1) 74*9880d681SAndroid Build Coastguard Worker %2 = bitcast %struct.A* %1 to i8*** 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; CHECK: %vtable = load {{.*}} !invariant.group 77*9880d681SAndroid Build Coastguard Worker %vtable = load i8**, i8*** %2, align 8, !invariant.group !2 78*9880d681SAndroid Build Coastguard Worker %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) 79*9880d681SAndroid Build Coastguard Worker call void @llvm.assume(i1 %cmp.vtables) 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker store %struct.A* %1, %struct.A** %a, align 8 82*9880d681SAndroid Build Coastguard Worker %3 = load %struct.A*, %struct.A** %a, align 8 83*9880d681SAndroid Build Coastguard Worker %4 = bitcast %struct.A* %3 to void (%struct.A*)*** 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv( 86*9880d681SAndroid Build Coastguard Worker %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2 87*9880d681SAndroid Build Coastguard Worker %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0 88*9880d681SAndroid Build Coastguard Worker %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8 89*9880d681SAndroid Build Coastguard Worker call void %5(%struct.A* %3) 90*9880d681SAndroid Build Coastguard Worker %6 = load %struct.A*, %struct.A** %a, align 8 91*9880d681SAndroid Build Coastguard Worker %7 = bitcast %struct.A* %6 to void (%struct.A*)*** 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv( 94*9880d681SAndroid Build Coastguard Worker %vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !2 95*9880d681SAndroid Build Coastguard Worker %vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0 96*9880d681SAndroid Build Coastguard Worker %8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker call void %8(%struct.A* %6) 99*9880d681SAndroid Build Coastguard Worker %9 = load %struct.A*, %struct.A** %a, align 8 100*9880d681SAndroid Build Coastguard Worker %10 = bitcast %struct.A* %9 to void (%struct.A*)*** 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker %vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !2 103*9880d681SAndroid Build Coastguard Worker %vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0 104*9880d681SAndroid Build Coastguard Worker %11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8 105*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv( 106*9880d681SAndroid Build Coastguard Worker call void %11(%struct.A* %9) 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker %vtable5 = load i8**, i8*** %2, align 8, !invariant.group !2 109*9880d681SAndroid Build Coastguard Worker %vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0 110*9880d681SAndroid Build Coastguard Worker %12 = bitcast i8** %vfn6 to void (%struct.A*)** 111*9880d681SAndroid Build Coastguard Worker %13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8 112*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv( 113*9880d681SAndroid Build Coastguard Worker call void %13(%struct.A* %9) 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker ret void 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @combiningBitCastWithLoad() { 119*9880d681SAndroid Build Coastguard Workerdefine void @combiningBitCastWithLoad() { 120*9880d681SAndroid Build Coastguard Workerentry: 121*9880d681SAndroid Build Coastguard Worker %a = alloca %struct.A*, align 8 122*9880d681SAndroid Build Coastguard Worker %0 = bitcast %struct.A** %a to i8* 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker %call = call i8* @getPointer(i8* null) 125*9880d681SAndroid Build Coastguard Worker %1 = bitcast i8* %call to %struct.A* 126*9880d681SAndroid Build Coastguard Worker call void @_ZN1AC1Ev(%struct.A* %1) 127*9880d681SAndroid Build Coastguard Worker %2 = bitcast %struct.A* %1 to i8*** 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker; CHECK: %vtable = load {{.*}} !invariant.group 130*9880d681SAndroid Build Coastguard Worker %vtable = load i8**, i8*** %2, align 8, !invariant.group !2 131*9880d681SAndroid Build Coastguard Worker %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker store %struct.A* %1, %struct.A** %a, align 8 134*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !invariant.group 135*9880d681SAndroid Build Coastguard Worker %3 = load %struct.A*, %struct.A** %a, align 8 136*9880d681SAndroid Build Coastguard Worker %4 = bitcast %struct.A* %3 to void (%struct.A*)*** 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2 139*9880d681SAndroid Build Coastguard Worker %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0 140*9880d681SAndroid Build Coastguard Worker %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8 141*9880d681SAndroid Build Coastguard Worker call void %5(%struct.A* %3) 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL:define void @loadCombine() { 147*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine() { 148*9880d681SAndroid Build Coastguard Workerenter: 149*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 150*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr 151*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 152*9880d681SAndroid Build Coastguard Worker; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group 153*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 154*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 155*9880d681SAndroid Build Coastguard Worker %b = load i8, i8* %ptr, !invariant.group !1 156*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[A]]) 157*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %a) 158*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[A]]) 159*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %b) 160*9880d681SAndroid Build Coastguard Worker ret void 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @loadCombine1() { 164*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine1() { 165*9880d681SAndroid Build Coastguard Workerenter: 166*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 167*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr 168*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 169*9880d681SAndroid Build Coastguard Worker; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group 170*9880d681SAndroid Build Coastguard Worker %c = load i8, i8* %ptr 171*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 172*9880d681SAndroid Build Coastguard Worker %d = load i8, i8* %ptr, !invariant.group !1 173*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[D]]) 174*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %c) 175*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[D]]) 176*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %d) 177*9880d681SAndroid Build Coastguard Worker ret void 178*9880d681SAndroid Build Coastguard Worker} 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @loadCombine2() { 181*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine2() { 182*9880d681SAndroid Build Coastguard Workerenter: 183*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 184*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr 185*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 186*9880d681SAndroid Build Coastguard Worker; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group 187*9880d681SAndroid Build Coastguard Worker %e = load i8, i8* %ptr, !invariant.group !1 188*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 189*9880d681SAndroid Build Coastguard Worker %f = load i8, i8* %ptr 190*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]]) 191*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %e) 192*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]]) 193*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %f) 194*9880d681SAndroid Build Coastguard Worker ret void 195*9880d681SAndroid Build Coastguard Worker} 196*9880d681SAndroid Build Coastguard Worker 197*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @loadCombine3() { 198*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine3() { 199*9880d681SAndroid Build Coastguard Workerenter: 200*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 201*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr 202*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 203*9880d681SAndroid Build Coastguard Worker; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group ![[OneMD:[0-9]]] 204*9880d681SAndroid Build Coastguard Worker %e = load i8, i8* %ptr, !invariant.group !1 205*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 206*9880d681SAndroid Build Coastguard Worker %f = load i8, i8* %ptr, !invariant.group !1 207*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]]) 208*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %e) 209*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]]) 210*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %f) 211*9880d681SAndroid Build Coastguard Worker ret void 212*9880d681SAndroid Build Coastguard Worker} 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable2() { 215*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable2() { 216*9880d681SAndroid Build Coastguard Workerentry: 217*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 218*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr 219*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 220*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr 221*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 222*9880d681SAndroid Build Coastguard Worker %b = load i8, i8* %ptr, !invariant.group !0 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a 225*9880d681SAndroid Build Coastguard Worker ret i8 %a 226*9880d681SAndroid Build Coastguard Worker} 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable3() { 229*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable3() { 230*9880d681SAndroid Build Coastguard Workerentry: 231*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 232*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 233*9880d681SAndroid Build Coastguard Worker %ptr2 = call i8* @getPointer(i8* %ptr) 234*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr2, !invariant.group !0 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a 237*9880d681SAndroid Build Coastguard Worker ret i8 %a 238*9880d681SAndroid Build Coastguard Worker} 239*9880d681SAndroid Build Coastguard Worker 240*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable4() { 241*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable4() { 242*9880d681SAndroid Build Coastguard Workerentry: 243*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 244*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 245*9880d681SAndroid Build Coastguard Worker %ptr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr) 246*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr2, !invariant.group !0 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a 249*9880d681SAndroid Build Coastguard Worker ret i8 %a 250*9880d681SAndroid Build Coastguard Worker} 251*9880d681SAndroid Build Coastguard Worker 252*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @volatile1() { 253*9880d681SAndroid Build Coastguard Workerdefine i8 @volatile1() { 254*9880d681SAndroid Build Coastguard Workerentry: 255*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 256*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 257*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 258*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 259*9880d681SAndroid Build Coastguard Worker %b = load volatile i8, i8* %ptr 260*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %b) 261*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %b) 262*9880d681SAndroid Build Coastguard Worker 263*9880d681SAndroid Build Coastguard Worker %c = load volatile i8, i8* %ptr, !invariant.group !0 264*9880d681SAndroid Build Coastguard Worker; FIXME: we could change %c to 42, preserving volatile load 265*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %c) 266*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %c) 267*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42 268*9880d681SAndroid Build Coastguard Worker ret i8 %a 269*9880d681SAndroid Build Coastguard Worker} 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @volatile2() { 272*9880d681SAndroid Build Coastguard Workerdefine i8 @volatile2() { 273*9880d681SAndroid Build Coastguard Workerentry: 274*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 275*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 276*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 277*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 278*9880d681SAndroid Build Coastguard Worker %b = load volatile i8, i8* %ptr 279*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %b) 280*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %b) 281*9880d681SAndroid Build Coastguard Worker 282*9880d681SAndroid Build Coastguard Worker %c = load volatile i8, i8* %ptr, !invariant.group !0 283*9880d681SAndroid Build Coastguard Worker; FIXME: we could change %c to 42, preserving volatile load 284*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %c) 285*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %c) 286*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42 287*9880d681SAndroid Build Coastguard Worker ret i8 %a 288*9880d681SAndroid Build Coastguard Worker} 289*9880d681SAndroid Build Coastguard Worker 290*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @fun() { 291*9880d681SAndroid Build Coastguard Workerdefine i8 @fun() { 292*9880d681SAndroid Build Coastguard Workerentry: 293*9880d681SAndroid Build Coastguard Worker %ptr = alloca i8 294*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %ptr, !invariant.group !0 295*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Worker %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change 298*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 42) 299*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %a) 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard Worker call void @foo(i8* %ptr) 302*9880d681SAndroid Build Coastguard Worker %b = load i8, i8* %ptr, !invariant.group !1 ; Can't assume anything, because group changed 303*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %b) 304*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %b) 305*9880d681SAndroid Build Coastguard Worker 306*9880d681SAndroid Build Coastguard Worker %newPtr = call i8* @getPointer(i8* %ptr) 307*9880d681SAndroid Build Coastguard Worker %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr 308*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %c) 309*9880d681SAndroid Build Coastguard Worker call void @bar(i8 %c) 310*9880d681SAndroid Build Coastguard Worker 311*9880d681SAndroid Build Coastguard Worker %unknownValue = load i8, i8* @unknownPtr 312*9880d681SAndroid Build Coastguard Worker; FIXME: Can assume that %unknownValue == 42 313*9880d681SAndroid Build Coastguard Worker; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0 314*9880d681SAndroid Build Coastguard Worker store i8 %unknownValue, i8* %ptr, !invariant.group !0 315*9880d681SAndroid Build Coastguard Worker 316*9880d681SAndroid Build Coastguard Worker %newPtr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr) 317*9880d681SAndroid Build Coastguard Worker %d = load i8, i8* %newPtr2, !invariant.group !0 ; Can't step through invariant.group.barrier to get value of %ptr 318*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %d 319*9880d681SAndroid Build Coastguard Worker ret i8 %d 320*9880d681SAndroid Build Coastguard Worker} 321*9880d681SAndroid Build Coastguard Worker 322*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i8*) 323*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i8) 324*9880d681SAndroid Build Coastguard Workerdeclare i8* @getPointer(i8*) 325*9880d681SAndroid Build Coastguard Workerdeclare void @_ZN1A3fooEv(%struct.A*) 326*9880d681SAndroid Build Coastguard Workerdeclare void @_ZN1AC1Ev(%struct.A*) 327*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.invariant.group.barrier(i8*) 328*9880d681SAndroid Build Coastguard Worker 329*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind 330*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.assume(i1 %cmp.vtables) #0 331*9880d681SAndroid Build Coastguard Worker 332*9880d681SAndroid Build Coastguard Worker 333*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind } 334*9880d681SAndroid Build Coastguard Worker; CHECK: ![[OneMD]] = !{!"other ptr"} 335*9880d681SAndroid Build Coastguard Worker!0 = !{!"magic ptr"} 336*9880d681SAndroid Build Coastguard Worker!1 = !{!"other ptr"} 337*9880d681SAndroid Build Coastguard Worker!2 = !{!"vtable_of_a"} 338