; RUN: opt -S -passes=early-cse -earlycse-debug-hash < %s | FileCheck %s ; RUN: opt -S -passes=gvn < %s | FileCheck %s ; RUN: opt -S -passes=newgvn < %s | FileCheck %s ; These tests checks if passes with CSE functionality can do CSE on ; launder.invariant.group, that is prohibited if there is a memory clobber ; between barriers call. ; CHECK-LABEL: define i8 @optimizable() define i8 @optimizable() { entry: %ptr = alloca i8 store i8 42, ptr %ptr, !invariant.group !0 ; CHECK: call ptr @llvm.launder.invariant.group.p0 %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) ; FIXME: This one could be CSE ; CHECK: call ptr @llvm.launder.invariant.group %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) ; CHECK: call void @clobber(ptr {{.*}}%ptr) call void @clobber(ptr %ptr) ; CHECK: call void @use(ptr {{.*}}%ptr2) call void @use(ptr %ptr2) ; CHECK: call void @use(ptr {{.*}}%ptr3) call void @use(ptr %ptr3) ; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group %v = load i8, ptr %ptr3, !invariant.group !0 ret i8 %v } ; CHECK-LABEL: define i8 @unoptimizable() define i8 @unoptimizable() { entry: %ptr = alloca i8 store i8 42, ptr %ptr, !invariant.group !0 ; CHECK: call ptr @llvm.launder.invariant.group.p0 %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) call void @clobber(ptr %ptr) ; CHECK: call ptr @llvm.launder.invariant.group.p0 %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) ; CHECK: call void @clobber(ptr {{.*}}%ptr) call void @clobber(ptr %ptr) ; CHECK: call void @use(ptr {{.*}}%ptr2) call void @use(ptr %ptr2) ; CHECK: call void @use(ptr {{.*}}%ptr3) call void @use(ptr %ptr3) ; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group %v = load i8, ptr %ptr3, !invariant.group !0 ret i8 %v } ; CHECK-LABEL: define i8 @unoptimizable2() define i8 @unoptimizable2() { %ptr = alloca i8 store i8 42, ptr %ptr, !invariant.group !0 ; CHECK: call ptr @llvm.launder.invariant.group %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) store i8 43, ptr %ptr ; CHECK: call ptr @llvm.launder.invariant.group %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr) ; CHECK: call void @clobber(ptr {{.*}}%ptr) call void @clobber(ptr %ptr) ; CHECK: call void @use(ptr {{.*}}%ptr2) call void @use(ptr %ptr2) ; CHECK: call void @use(ptr {{.*}}%ptr3) call void @use(ptr %ptr3) ; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group %v = load i8, ptr %ptr3, !invariant.group !0 ret i8 %v } ; This test check if optimizer is not proving equality based on mustalias ; CHECK-LABEL: define void @dontProveEquality(ptr %a) define void @dontProveEquality(ptr %a) { %b = call ptr @llvm.launder.invariant.group.p0(ptr %a) %r = icmp eq ptr %b, %a ; CHECK: call void @useBool(i1 %r) call void @useBool(i1 %r) %b2 = call ptr @llvm.strip.invariant.group.p0(ptr %a) %r2 = icmp eq ptr %b2, %a ; CHECK: call void @useBool(i1 %r2) call void @useBool(i1 %r2) ret void } declare void @use(ptr readonly) declare void @useBool(i1) declare void @clobber(ptr) ; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite){{$}} ; CHECK-NEXT: declare ptr @llvm.launder.invariant.group.p0(ptr) declare ptr @llvm.launder.invariant.group.p0(ptr) ; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none){{$}} ; CHECK-NEXT: declare ptr @llvm.strip.invariant.group.p0(ptr) declare ptr @llvm.strip.invariant.group.p0(ptr) !0 = !{}