1 ; Test to make sure llvm.invariant.start calls are not treated as clobbers. 2 ; RUN: opt < %s -gvn -S | FileCheck %s 3 4 5 declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) nounwind readonly 6 declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind 7 8 ; We forward store to the load across the invariant.start intrinsic 9 define i8 @forward_store() { 10 ; CHECK-LABEL: @forward_store 11 ; CHECK: call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) 12 ; CHECK-NOT: load 13 ; CHECK: ret i8 0 14 %a = alloca i8 15 store i8 0, i8* %a 16 %i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) 17 %r = load i8, i8* %a 18 ret i8 %r 19 } 20 21 declare i8 @dummy(i8* nocapture) nounwind readonly 22 23 ; We forward store to the load in the non-local analysis case, 24 ; i.e. invariant.start is in another basic block. 25 define i8 @forward_store_nonlocal(i1 %cond) { 26 ; CHECK-LABEL: forward_store_nonlocal 27 ; CHECK: call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) 28 ; CHECK: ret i8 0 29 ; CHECK: ret i8 %val 30 %a = alloca i8 31 store i8 0, i8* %a 32 %i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) 33 br i1 %cond, label %loadblock, label %exit 34 35 loadblock: 36 %r = load i8, i8* %a 37 ret i8 %r 38 39 exit: 40 %val = call i8 @dummy(i8* %a) 41 ret i8 %val 42 } 43 44 ; We should not value forward %foo to the invariant.end corresponding to %bar. 45 define i8 @forward_store1() { 46 ; CHECK-LABEL: forward_store1 47 ; CHECK: %foo = call {}* @llvm.invariant.start.p0i8 48 ; CHECK-NOT: load 49 ; CHECK: %bar = call {}* @llvm.invariant.start.p0i8 50 ; CHECK: call void @llvm.invariant.end.p0i8({}* %bar, i64 1, i8* %a) 51 ; CHECK: ret i8 0 52 %a = alloca i8 53 store i8 0, i8* %a 54 %foo = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) 55 %r = load i8, i8* %a 56 %bar = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) 57 call void @llvm.invariant.end.p0i8({}* %bar, i64 1, i8* %a) 58 ret i8 %r 59 } 60