| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s |
| |
| ; A nonnull addrspacecast of the address space 0 null value is poison. |
| define ptr addrspace(1) @fold_scalar() { |
| ; CHECK-LABEL: @fold_scalar( |
| ; CHECK-NEXT: ret ptr addrspace(1) poison |
| ; |
| %c = addrspacecast nonnull ptr null to ptr addrspace(1) |
| ret ptr addrspace(1) %c |
| } |
| |
| ; A splat null vector of address space 0 pointers folds elementwise. |
| define <2 x ptr addrspace(1)> @fold_vector() { |
| ; CHECK-LABEL: @fold_vector( |
| ; CHECK-NEXT: ret <2 x ptr addrspace(1)> poison |
| ; |
| %c = addrspacecast nonnull <2 x ptr> zeroinitializer to <2 x ptr addrspace(1)> |
| ret <2 x ptr addrspace(1)> %c |
| } |
| |
| define <2 x ptr addrspace(1)> @no_fold_splat_poison() { |
| ; CHECK-LABEL: @no_fold_splat_poison( |
| ; CHECK-NEXT: ret <2 x ptr addrspace(1)> <ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1)), ptr addrspace(1) poison> |
| ; |
| %c = addrspacecast nonnull <2 x ptr> <ptr null, ptr poison> to <2 x ptr addrspace(1)> |
| ret <2 x ptr addrspace(1)> %c |
| } |
| |
| ; Without the nonnull flag the cast is not poison. |
| define ptr addrspace(1) @no_fold_without_flag() { |
| ; CHECK-LABEL: @no_fold_without_flag( |
| ; CHECK-NEXT: ret ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1)) |
| ; |
| %c = addrspacecast ptr null to ptr addrspace(1) |
| ret ptr addrspace(1) %c |
| } |
| |
| ; A non-null source is not folded. |
| define ptr addrspace(1) @no_fold_nonzero_src(ptr %p) { |
| ; CHECK-LABEL: @no_fold_nonzero_src( |
| ; CHECK-NEXT: [[C:%.*]] = addrspacecast nonnull ptr [[P:%.*]] to ptr addrspace(1) |
| ; CHECK-NEXT: ret ptr addrspace(1) [[C]] |
| ; |
| %c = addrspacecast nonnull ptr %p to ptr addrspace(1) |
| ret ptr addrspace(1) %c |
| } |
| |
| ; The null value of a non-zero source address space is not necessarily the zero |
| ; pointer, so casting it is not folded to poison. |
| define ptr @no_fold_src_as1() { |
| ; CHECK-LABEL: @no_fold_src_as1( |
| ; CHECK-NEXT: ret ptr addrspacecast (ptr addrspace(1) null to ptr) |
| ; |
| %c = addrspacecast nonnull ptr addrspace(1) null to ptr |
| ret ptr %c |
| } |
| |
| ; When null is a valid address for the function, the source may legitimately be |
| ; the null pointer, so the fold does not apply. |
| define ptr addrspace(1) @no_fold_null_valid() #0 { |
| ; CHECK-LABEL: @no_fold_null_valid( |
| ; CHECK-NEXT: ret ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1)) |
| ; |
| %c = addrspacecast nonnull ptr null to ptr addrspace(1) |
| ret ptr addrspace(1) %c |
| } |
| |
| attributes #0 = { null_pointer_is_valid } |