; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes=instcombine,early-cse -earlycse-debug-hash -S < %s | FileCheck %s define ptr @simplifyNullLaunder() { ; CHECK-LABEL: @simplifyNullLaunder( ; CHECK-NEXT: ret ptr null ; %b2 = call ptr @llvm.launder.invariant.group.p0(ptr null) ret ptr %b2 } define ptr @dontSimplifyNullLaunderNoNullOpt() #0 { ; CHECK-LABEL: @dontSimplifyNullLaunderNoNullOpt( ; CHECK-NEXT: [[B2:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr null) ; CHECK-NEXT: ret ptr [[B2]] ; %b2 = call ptr @llvm.launder.invariant.group.p0(ptr null) ret ptr %b2 } define ptr addrspace(42) @dontsimplifyNullLaunderForDifferentAddrspace() { ; CHECK-LABEL: @dontsimplifyNullLaunderForDifferentAddrspace( ; CHECK-NEXT: [[B2:%.*]] = call ptr addrspace(42) @llvm.launder.invariant.group.p42(ptr addrspace(42) null) ; CHECK-NEXT: ret ptr addrspace(42) [[B2]] ; %b2 = call ptr addrspace(42) @llvm.launder.invariant.group.p42(ptr addrspace(42) null) ret ptr addrspace(42) %b2 } define ptr @simplifyUndefLaunder() { ; CHECK-LABEL: @simplifyUndefLaunder( ; CHECK-NEXT: ret ptr undef ; %b2 = call ptr @llvm.launder.invariant.group.p0(ptr undef) ret ptr %b2 } define ptr addrspace(42) @simplifyUndefLaunder2() { ; CHECK-LABEL: @simplifyUndefLaunder2( ; CHECK-NEXT: ret ptr addrspace(42) undef ; %b2 = call ptr addrspace(42) @llvm.launder.invariant.group.p42(ptr addrspace(42) undef) ret ptr addrspace(42) %b2 } define ptr @simplifyNullStrip() { ; CHECK-LABEL: @simplifyNullStrip( ; CHECK-NEXT: ret ptr null ; %b2 = call ptr @llvm.strip.invariant.group.p0(ptr null) ret ptr %b2 } define ptr @dontSimplifyNullStripNonNullOpt() #0 { ; CHECK-LABEL: @dontSimplifyNullStripNonNullOpt( ; CHECK-NEXT: [[B2:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr null) ; CHECK-NEXT: ret ptr [[B2]] ; %b2 = call ptr @llvm.strip.invariant.group.p0(ptr null) ret ptr %b2 } define ptr addrspace(42) @dontsimplifyNullStripForDifferentAddrspace() { ; CHECK-LABEL: @dontsimplifyNullStripForDifferentAddrspace( ; CHECK-NEXT: [[B2:%.*]] = call ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42) null) ; CHECK-NEXT: ret ptr addrspace(42) [[B2]] ; %b2 = call ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42) null) ret ptr addrspace(42) %b2 } define ptr @simplifyUndefStrip() { ; CHECK-LABEL: @simplifyUndefStrip( ; CHECK-NEXT: ret ptr undef ; %b2 = call ptr @llvm.strip.invariant.group.p0(ptr undef) ret ptr %b2 } define ptr addrspace(42) @simplifyUndefStrip2() { ; CHECK-LABEL: @simplifyUndefStrip2( ; CHECK-NEXT: ret ptr addrspace(42) undef ; %b2 = call ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42) undef) ret ptr addrspace(42) %b2 } define ptr @simplifyLaunderOfLaunder(ptr %a) { ; CHECK-LABEL: @simplifyLaunderOfLaunder( ; CHECK-NEXT: [[A3:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: ret ptr [[A3]] ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %a3 = call ptr @llvm.launder.invariant.group.p0(ptr %a2) ret ptr %a3 } define ptr @simplifyStripOfLaunder(ptr %a) { ; CHECK-LABEL: @simplifyStripOfLaunder( ; CHECK-NEXT: [[A3:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: ret ptr [[A3]] ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %a3 = call ptr @llvm.strip.invariant.group.p0(ptr %a2) ret ptr %a3 } define i1 @simplifyForCompare(ptr %a) { ; CHECK-LABEL: @simplifyForCompare( ; CHECK-NEXT: [[A3:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: ret i1 true ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %a3 = call ptr @llvm.strip.invariant.group.p0(ptr %a2) %b2 = call ptr @llvm.strip.invariant.group.p0(ptr %a) %c = icmp eq ptr %a3, %b2 ret i1 %c } define ptr @skipWithDifferentTypes(ptr %a) { ; CHECK-LABEL: @skipWithDifferentTypes( ; CHECK-NEXT: [[A3:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: ret ptr [[A3]] ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %a3 = call ptr @llvm.strip.invariant.group.p0(ptr %a2) ret ptr %a3 } define ptr addrspace(42) @skipWithDifferentTypesAddrspace(ptr addrspace(42) %a) { ; CHECK-LABEL: @skipWithDifferentTypesAddrspace( ; CHECK-NEXT: [[A3:%.*]] = call ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42) [[A:%.*]]) ; CHECK-NEXT: ret ptr addrspace(42) [[A3]] ; %a2 = call ptr addrspace(42) @llvm.launder.invariant.group.p42(ptr addrspace(42) %a) %a3 = call ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42) %a2) ret ptr addrspace(42) %a3 } define ptr addrspace(42) @skipWithDifferentTypesDifferentAddrspace(ptr %a) { ; CHECK-LABEL: @skipWithDifferentTypesDifferentAddrspace( ; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: [[A3:%.*]] = addrspacecast ptr [[TMP1]] to ptr addrspace(42) ; CHECK-NEXT: ret ptr addrspace(42) [[A3]] ; %cast = addrspacecast ptr %a to ptr addrspace(42) %a2 = call ptr addrspace(42) @llvm.launder.invariant.group.p42(ptr addrspace(42) %cast) %a3 = call ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42) %a2) ret ptr addrspace(42) %a3 } define i1 @icmp_null_launder(ptr %a) { ; CHECK-LABEL: @icmp_null_launder( ; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A:%.*]], null ; CHECK-NEXT: ret i1 [[R]] ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %r = icmp eq ptr %a2, null ret i1 %r } define i1 @icmp_null_strip(ptr %a) { ; CHECK-LABEL: @icmp_null_strip( ; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A:%.*]], null ; CHECK-NEXT: ret i1 [[R]] ; %a2 = call ptr @llvm.strip.invariant.group.p0(ptr %a) %r = icmp eq ptr %a2, null ret i1 %r } define i1 @icmp_null_launder_valid_null(ptr %a) #0 { ; CHECK-LABEL: @icmp_null_launder_valid_null( ; CHECK-NEXT: [[A2:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A2]], null ; CHECK-NEXT: ret i1 [[R]] ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %r = icmp eq ptr %a2, null ret i1 %r } define i1 @icmp_null_strip_valid_null(ptr %a) #0 { ; CHECK-LABEL: @icmp_null_strip_valid_null( ; CHECK-NEXT: [[A2:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[A:%.*]]) ; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A2]], null ; CHECK-NEXT: ret i1 [[R]] ; %a2 = call ptr @llvm.strip.invariant.group.p0(ptr %a) %r = icmp eq ptr %a2, null ret i1 %r } ; Check that null always becomes the RHS define i1 @icmp_null_launder_lhs(ptr %a) { ; CHECK-LABEL: @icmp_null_launder_lhs( ; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A:%.*]], null ; CHECK-NEXT: ret i1 [[R]] ; %a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %r = icmp eq ptr null, %a2 ret i1 %r } define i1 @icmp_null_launder_bitcasts(ptr %a) { ; CHECK-LABEL: @icmp_null_launder_bitcasts( ; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A:%.*]], null ; CHECK-NEXT: ret i1 [[R]] ; %a3 = call ptr @llvm.launder.invariant.group.p0(ptr %a) %r = icmp eq ptr %a3, null ret i1 %r } declare ptr @llvm.launder.invariant.group.p0(ptr) declare ptr addrspace(42) @llvm.launder.invariant.group.p42(ptr addrspace(42)) declare ptr @llvm.strip.invariant.group.p0(ptr) declare ptr addrspace(42) @llvm.strip.invariant.group.p42(ptr addrspace(42)) attributes #0 = { null_pointer_is_valid }