1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; Test to make sure llvm.invariant.start calls are not treated as clobbers. 3; RUN: opt < %s -passes=newgvn -S | FileCheck %s 4 5 6declare ptr @llvm.invariant.start.p0(i64, ptr nocapture) nounwind readonly 7declare void @llvm.invariant.end.p0(ptr, i64, ptr nocapture) nounwind 8 9; We forward store to the load across the invariant.start intrinsic 10define i8 @forward_store() { 11; CHECK-LABEL: define i8 @forward_store() { 12; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 13; CHECK-NEXT: store i8 0, ptr [[A]], align 1 14; CHECK-NEXT: [[I:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]]) 15; CHECK-NEXT: ret i8 0 16; 17 %a = alloca i8 18 store i8 0, ptr %a 19 %i = call ptr @llvm.invariant.start.p0(i64 1, ptr %a) 20 %r = load i8, ptr %a 21 ret i8 %r 22} 23 24declare i8 @dummy(ptr nocapture) nounwind readonly 25 26; We forward store to the load in the non-local analysis case, 27; i.e. invariant.start is in another basic block. 28define i8 @forward_store_nonlocal(i1 %cond) { 29; CHECK-LABEL: define i8 @forward_store_nonlocal( 30; CHECK-SAME: i1 [[COND:%.*]]) { 31; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 32; CHECK-NEXT: store i8 0, ptr [[A]], align 1 33; CHECK-NEXT: [[I:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]]) 34; CHECK-NEXT: br i1 [[COND]], label [[LOADBLOCK:%.*]], label [[EXIT:%.*]] 35; CHECK: loadblock: 36; CHECK-NEXT: ret i8 0 37; CHECK: exit: 38; CHECK-NEXT: [[VAL:%.*]] = call i8 @dummy(ptr [[A]]) 39; CHECK-NEXT: ret i8 [[VAL]] 40; 41 %a = alloca i8 42 store i8 0, ptr %a 43 %i = call ptr @llvm.invariant.start.p0(i64 1, ptr %a) 44 br i1 %cond, label %loadblock, label %exit 45 46loadblock: 47 %r = load i8, ptr %a 48 ret i8 %r 49 50exit: 51 %val = call i8 @dummy(ptr %a) 52 ret i8 %val 53} 54 55; We should not value forward %foo to the invariant.end corresponding to %bar. 56define i8 @forward_store1() { 57; CHECK-LABEL: define i8 @forward_store1() { 58; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 59; CHECK-NEXT: store i8 0, ptr [[A]], align 1 60; CHECK-NEXT: [[FOO:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]]) 61; CHECK-NEXT: [[BAR:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]]) 62; CHECK-NEXT: call void @llvm.invariant.end.p0(ptr [[BAR]], i64 1, ptr [[A]]) 63; CHECK-NEXT: ret i8 0 64; 65 %a = alloca i8 66 store i8 0, ptr %a 67 %foo = call ptr @llvm.invariant.start.p0(i64 1, ptr %a) 68 %r = load i8, ptr %a 69 %bar = call ptr @llvm.invariant.start.p0(i64 1, ptr %a) 70 call void @llvm.invariant.end.p0(ptr %bar, i64 1, ptr %a) 71 ret i8 %r 72} 73