1; RUN: opt -S -passes=early-cse -earlycse-debug-hash < %s | FileCheck %s 2; RUN: opt -S -passes=gvn < %s | FileCheck %s 3; RUN: opt -S -passes=newgvn < %s | FileCheck %s 4 5; These tests checks if passes with CSE functionality can do CSE on 6; launder.invariant.group, that is prohibited if there is a memory clobber 7; between barriers call. 8 9; CHECK-LABEL: define i8 @optimizable() 10define i8 @optimizable() { 11entry: 12 %ptr = alloca i8 13 store i8 42, ptr %ptr, !invariant.group !0 14; CHECK: call ptr @llvm.launder.invariant.group.p0 15 %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) 16; FIXME: This one could be CSE 17; CHECK: call ptr @llvm.launder.invariant.group 18 %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) 19; CHECK: call void @clobber(ptr {{.*}}%ptr) 20 call void @clobber(ptr %ptr) 21 22; CHECK: call void @use(ptr {{.*}}%ptr2) 23 call void @use(ptr %ptr2) 24; CHECK: call void @use(ptr {{.*}}%ptr3) 25 call void @use(ptr %ptr3) 26; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group 27 %v = load i8, ptr %ptr3, !invariant.group !0 28 29 ret i8 %v 30} 31 32; CHECK-LABEL: define i8 @unoptimizable() 33define i8 @unoptimizable() { 34entry: 35 %ptr = alloca i8 36 store i8 42, ptr %ptr, !invariant.group !0 37; CHECK: call ptr @llvm.launder.invariant.group.p0 38 %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) 39 call void @clobber(ptr %ptr) 40; CHECK: call ptr @llvm.launder.invariant.group.p0 41 %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) 42; CHECK: call void @clobber(ptr {{.*}}%ptr) 43 call void @clobber(ptr %ptr) 44; CHECK: call void @use(ptr {{.*}}%ptr2) 45 call void @use(ptr %ptr2) 46; CHECK: call void @use(ptr {{.*}}%ptr3) 47 call void @use(ptr %ptr3) 48; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group 49 %v = load i8, ptr %ptr3, !invariant.group !0 50 51 ret i8 %v 52} 53 54; CHECK-LABEL: define i8 @unoptimizable2() 55define i8 @unoptimizable2() { 56 %ptr = alloca i8 57 store i8 42, ptr %ptr, !invariant.group !0 58; CHECK: call ptr @llvm.launder.invariant.group 59 %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) 60 store i8 43, ptr %ptr 61; CHECK: call ptr @llvm.launder.invariant.group 62 %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) 63; CHECK: call void @clobber(ptr {{.*}}%ptr) 64 call void @clobber(ptr %ptr) 65; CHECK: call void @use(ptr {{.*}}%ptr2) 66 call void @use(ptr %ptr2) 67; CHECK: call void @use(ptr {{.*}}%ptr3) 68 call void @use(ptr %ptr3) 69; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group 70 %v = load i8, ptr %ptr3, !invariant.group !0 71 ret i8 %v 72} 73 74; This test check if optimizer is not proving equality based on mustalias 75; CHECK-LABEL: define void @dontProveEquality(ptr %a) 76define void @dontProveEquality(ptr %a) { 77 %b = call ptr @llvm.launder.invariant.group.p0(ptr %a) 78 %r = icmp eq ptr %b, %a 79; CHECK: call void @useBool(i1 %r) 80 call void @useBool(i1 %r) 81 82 %b2 = call ptr @llvm.strip.invariant.group.p0(ptr %a) 83 %r2 = icmp eq ptr %b2, %a 84; CHECK: call void @useBool(i1 %r2) 85 call void @useBool(i1 %r2) 86 87 ret void 88} 89 90declare void @use(ptr readonly) 91declare void @useBool(i1) 92 93declare void @clobber(ptr) 94; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite){{$}} 95; CHECK-NEXT: declare ptr @llvm.launder.invariant.group.p0(ptr) 96declare ptr @llvm.launder.invariant.group.p0(ptr) 97 98; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none){{$}} 99; CHECK-NEXT: declare ptr @llvm.strip.invariant.group.p0(ptr) 100declare ptr @llvm.strip.invariant.group.p0(ptr) 101 102 103!0 = !{} 104