1*9880d681SAndroid Build Coastguard Worker; Test if the !invariant.load metadata is maintained by GVN. 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -gvn -S < %s | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32* nocapture %p, i8* nocapture %q) { 5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1 6*9880d681SAndroid Build Coastguard Worker; CHECK: %x = load i32, i32* %p, align 4, !invariant.load !0 7*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %y = load 8*9880d681SAndroid Build Coastguard Workerentry: 9*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* %p, align 4, !invariant.load !0 10*9880d681SAndroid Build Coastguard Worker %conv = trunc i32 %x to i8 11*9880d681SAndroid Build Coastguard Worker store i8 %conv, i8* %q, align 1 12*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p, align 4, !invariant.load !0 13*9880d681SAndroid Build Coastguard Worker %add = add i32 %y, 1 14*9880d681SAndroid Build Coastguard Worker ret i32 %add 15*9880d681SAndroid Build Coastguard Worker} 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32* nocapture %p, i8* nocapture %q) { 18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test2 19*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !invariant.load 20*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %y = load 21*9880d681SAndroid Build Coastguard Workerentry: 22*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* %p, align 4 23*9880d681SAndroid Build Coastguard Worker %conv = trunc i32 %x to i8 24*9880d681SAndroid Build Coastguard Worker store i8 %conv, i8* %q, align 1 25*9880d681SAndroid Build Coastguard Worker %y = load i32, i32* %p, align 4, !invariant.load !0 26*9880d681SAndroid Build Coastguard Worker %add = add i32 %y, 1 27*9880d681SAndroid Build Coastguard Worker ret i32 %add 28*9880d681SAndroid Build Coastguard Worker} 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker; With the invariant.load metadata, what would otherwise 31*9880d681SAndroid Build Coastguard Worker; be a case for PRE becomes a full redundancy. 32*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i1 %cnd, i32* %p, i32* %q) { 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3 34*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 35*9880d681SAndroid Build Coastguard Workerentry: 36*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %p 37*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %bb1, label %bb2 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Workerbb1: 40*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %q 41*9880d681SAndroid Build Coastguard Worker br label %bb2 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerbb2: 44*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %p, !invariant.load !0 45*9880d681SAndroid Build Coastguard Worker %res = sub i32 %v1, %v2 46*9880d681SAndroid Build Coastguard Worker ret i32 %res 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; This test is here to document a case which doesn't optimize 50*9880d681SAndroid Build Coastguard Worker; as well as it could. 51*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i1 %cnd, i32* %p, i32* %q) { 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test4 53*9880d681SAndroid Build Coastguard Worker; %v2 is redundant, but GVN currently doesn't catch that 54*9880d681SAndroid Build Coastguard Workerentry: 55*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %p, !invariant.load !0 56*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %bb1, label %bb2 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerbb1: 59*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %q 60*9880d681SAndroid Build Coastguard Worker br label %bb2 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerbb2: 63*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %p 64*9880d681SAndroid Build Coastguard Worker %res = sub i32 %v1, %v2 65*9880d681SAndroid Build Coastguard Worker ret i32 %res 66*9880d681SAndroid Build Coastguard Worker} 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker; Checks that we return the mustalias store as a def 69*9880d681SAndroid Build Coastguard Worker; so that it contributes to value forwarding. Note 70*9880d681SAndroid Build Coastguard Worker; that we could and should remove the store too. 71*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i1 %cnd, i32* %p) { 72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test5 73*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: entry: 74*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store i32 5, i32* %p 75*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 5 76*9880d681SAndroid Build Coastguard Workerentry: 77*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %p, !invariant.load !0 78*9880d681SAndroid Build Coastguard Worker store i32 5, i32* %p ;; must alias store, want to exploit 79*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %p, !invariant.load !0 80*9880d681SAndroid Build Coastguard Worker ret i32 %v2 81*9880d681SAndroid Build Coastguard Worker} 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Workerdeclare void @foo() 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker; Clobbering (mayalias) stores, even in function calls, can be ignored 87*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i1 %cnd, i32* %p) { 88*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test6 89*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: entry: 90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @foo 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 0 92*9880d681SAndroid Build Coastguard Workerentry: 93*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %p, !invariant.load !0 94*9880d681SAndroid Build Coastguard Worker call void @foo() 95*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %p, !invariant.load !0 96*9880d681SAndroid Build Coastguard Worker %res = sub i32 %v1, %v2 97*9880d681SAndroid Build Coastguard Worker ret i32 %res 98*9880d681SAndroid Build Coastguard Worker} 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerdeclare noalias i32* @bar(...) 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker; Same as previous, but a function with a noalias result (since they're handled 103*9880d681SAndroid Build Coastguard Worker; differently in MDA) 104*9880d681SAndroid Build Coastguard Workerdefine i32 @test7(i1 %cnd, i32* %p) { 105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test7 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: entry: 107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @bar 108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 0 109*9880d681SAndroid Build Coastguard Workerentry: 110*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %p, !invariant.load !0 111*9880d681SAndroid Build Coastguard Worker call i32* (...) @bar(i32* %p) 112*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %p, !invariant.load !0 113*9880d681SAndroid Build Coastguard Worker %res = sub i32 %v1, %v2 114*9880d681SAndroid Build Coastguard Worker ret i32 %res 115*9880d681SAndroid Build Coastguard Worker} 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Workerdefine i32 @test8(i1 %cnd, i32* %p) { 118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test8 119*9880d681SAndroid Build Coastguard Worker; CHECK: @bar 120*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %p2, !invariant.load 121*9880d681SAndroid Build Coastguard Worker; CHECK: br label %merge 122*9880d681SAndroid Build Coastguard Workerentry: 123*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %p, !invariant.load !0 124*9880d681SAndroid Build Coastguard Worker br i1 %cnd, label %taken, label %merge 125*9880d681SAndroid Build Coastguard Workertaken: 126*9880d681SAndroid Build Coastguard Worker %p2 = call i32* (...) @bar(i32* %p) 127*9880d681SAndroid Build Coastguard Worker br label %merge 128*9880d681SAndroid Build Coastguard Workermerge: 129*9880d681SAndroid Build Coastguard Worker %p3 = phi i32* [%p, %entry], [%p2, %taken] 130*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %p3, !invariant.load !0 131*9880d681SAndroid Build Coastguard Worker %res = sub i32 %v1, %v2 132*9880d681SAndroid Build Coastguard Worker ret i32 %res 133*9880d681SAndroid Build Coastguard Worker} 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker!0 = !{ } 136*9880d681SAndroid Build Coastguard Worker 137