1; Test to make sure llvm.invariant.start calls are not treated as clobbers. 2; RUN: opt < %s -gvn -S | FileCheck %s 3 4 5declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) nounwind readonly 6declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind 7 8; We forward store to the load across the invariant.start intrinsic 9define 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 21declare 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. 25define 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 35loadblock: 36 %r = load i8, i8* %a 37 ret i8 %r 38 39exit: 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. 45define 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