; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -passes=attributor -S < %s | FileCheck %s define ptr @align_ptrmask_back_no_prop(ptr align 2 %x, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define noundef nonnull align 8 dereferenceable(4) ptr @align_ptrmask_back_no_prop( ; CHECK-SAME: ptr nofree writeonly align 2 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8 ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16 ; CHECK-NEXT: [[P:%.*]] = tail call noundef nonnull align 8 dereferenceable(4) ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR4:[0-9]+]] ; CHECK-NEXT: store float 1.000000e+00, ptr [[P]], align 8 ; CHECK-NEXT: ret ptr [[P]] ; %sel = select i1 %cmp1, i64 -32, i64 -8 %sel1 = select i1 %cmp2, i64 %sel, i64 -16 %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1) store float 1.0, ptr %p, align 8 ret ptr %p } define ptr @align_ptrmask_back_prop(ptr align 2 %x, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define noundef nonnull align 16 dereferenceable(4) ptr @align_ptrmask_back_prop( ; CHECK-SAME: ptr nofree writeonly align 16 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8 ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16 ; CHECK-NEXT: [[P:%.*]] = tail call noundef nonnull align 16 dereferenceable(4) ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR4]] ; CHECK-NEXT: store float 1.000000e+00, ptr [[P]], align 16 ; CHECK-NEXT: ret ptr [[P]] ; %sel = select i1 %cmp1, i64 -32, i64 -8 %sel1 = select i1 %cmp2, i64 %sel, i64 -16 %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1) store float 1.0, ptr %p, align 16 ret ptr %p } define ptr @align_ptrmask_forward_mask(ptr align 2 %x, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 8 ptr @align_ptrmask_forward_mask( ; CHECK-SAME: ptr nofree readnone align 2 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8 ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16 ; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %sel = select i1 %cmp1, i64 -32, i64 -8 %sel1 = select i1 %cmp2, i64 %sel, i64 -16 %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1) ret ptr %p } define ptr @align_ptrmask_forward_ptr(ptr align 16 %x, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 16 ptr @align_ptrmask_forward_ptr( ; CHECK-SAME: ptr nofree readnone align 16 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8 ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16 ; CHECK-NEXT: [[P:%.*]] = tail call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %sel = select i1 %cmp1, i64 -32, i64 -8 %sel1 = select i1 %cmp2, i64 %sel, i64 -16 %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1) ret ptr %p } define ptr @align_ptrmask_forward_nonconst_mask(ptr align 8 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 8 ptr @align_ptrmask_forward_nonconst_mask( ; CHECK-SAME: ptr nofree readnone align 8 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 [[Y]] ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16 ; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 [[SEL1]]) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %sel = select i1 %cmp1, i64 -32, i64 %y %sel1 = select i1 %cmp2, i64 %sel, i64 -16 %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1) ret ptr %p } define ptr @align_ptrmask_back_nonconst_mask(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define noundef nonnull align 8 dereferenceable(4) ptr @align_ptrmask_back_nonconst_mask( ; CHECK-SAME: ptr nofree writeonly align 8 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 [[Y]] ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16 ; CHECK-NEXT: [[P:%.*]] = tail call noundef nonnull align 8 dereferenceable(4) ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 [[SEL1]]) #[[ATTR4]] ; CHECK-NEXT: store float 1.000000e+00, ptr [[P]], align 8 ; CHECK-NEXT: ret ptr [[P]] ; %sel = select i1 %cmp1, i64 -32, i64 %y %sel1 = select i1 %cmp2, i64 %sel, i64 -16 %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1) store float 1.0, ptr %p, align 8 ret ptr %p } define ptr @align_ptrmask_back_const_back_noprop(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define noundef nonnull align 8 dereferenceable(4) ptr @align_ptrmask_back_const_back_noprop( ; CHECK-SAME: ptr nofree writeonly align 4 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[P:%.*]] = tail call noundef nonnull align 8 dereferenceable(4) ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -8) #[[ATTR4]] ; CHECK-NEXT: store float 1.000000e+00, ptr [[P]], align 8 ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -8) store float 1.0, ptr %p, align 8 ret ptr %p } define ptr @align_ptrmask_back_const_back_prop(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define noundef nonnull align 8 dereferenceable(4) ptr @align_ptrmask_back_const_back_prop( ; CHECK-SAME: ptr nofree writeonly align 8 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[P:%.*]] = tail call noundef nonnull align 8 dereferenceable(4) ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -2) #[[ATTR4]] ; CHECK-NEXT: store float 1.000000e+00, ptr [[P]], align 8 ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -2) store float 1.0, ptr %p, align 8 ret ptr %p } define ptr @align_ptrmask_back_const_forward_mask(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 8 ptr @align_ptrmask_back_const_forward_mask( ; CHECK-SAME: ptr nofree readnone align 4 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -8) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -8) ret ptr %p } define ptr @align_ptrmask_back_const_forward_ptr(ptr align 16 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 16 ptr @align_ptrmask_back_const_forward_ptr( ; CHECK-SAME: ptr nofree readnone align 16 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -8) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -8) ret ptr %p } ; FIXME: The store will create AAAlign for %ptr1, ; but the attribute didn't propagate through extractelement, need propagate define <2 x ptr> @ptrmask_v2p0_v2i64(<2 x ptr> align 2 %ptr, i64 %a) { ; CHECK-LABEL: define <2 x ptr> @ptrmask_v2p0_v2i64( ; CHECK-SAME: <2 x ptr> align 2 [[PTR:%.*]], i64 [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[RESULT:%.*]] = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[PTR]], <2 x i64> noundef splat (i64 -8)) #[[ATTR4]] ; CHECK-NEXT: [[PTR1:%.*]] = extractelement <2 x ptr> [[RESULT]], i32 0 ; CHECK-NEXT: [[PTR2:%.*]] = extractelement <2 x ptr> [[RESULT]], i32 1 ; CHECK-NEXT: store i64 [[A]], ptr [[PTR1]], align 16 ; CHECK-NEXT: store i64 [[A]], ptr [[PTR2]], align 16 ; CHECK-NEXT: ret <2 x ptr> [[RESULT]] ; %result = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %ptr, <2 x i64> splat(i64 -8)) %ptr1 = extractelement <2 x ptr> %result, i32 0 %ptr2 = extractelement <2 x ptr> %result, i32 1 store i64 %a, ptr %ptr1, align 16 store i64 %a, ptr %ptr2, align 16 ret <2 x ptr> %result } define ptr @align_ptrmask_forward_mask_positive(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 4 ptr @align_ptrmask_forward_mask_positive( ; CHECK-SAME: ptr nofree readnone align 4 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef 2) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 2) ret ptr %p } define ptr @align_ptrmask_forward_mask_poison(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 4 ptr @align_ptrmask_forward_mask_poison( ; CHECK-SAME: ptr nofree readnone align 4 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 poison) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 poison) ret ptr %p } define ptr @align_ptrmask_forward_mask_max(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 4294967296 ptr @align_ptrmask_forward_mask_max( ; CHECK-SAME: ptr nofree readnone align 4 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 4294967296 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -4294967296) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -4294967296) ret ptr %p } define ptr @align_ptrmask_forward_mask_max_plus_one(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 4294967296 ptr @align_ptrmask_forward_mask_max_plus_one( ; CHECK-SAME: ptr nofree readnone align 4 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 4294967296 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -8589934592) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -8589934592) ret ptr %p } define ptr @align_ptrmask_back_callsite(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) { ; CHECK-LABEL: define align 16 ptr @align_ptrmask_back_callsite( ; CHECK-SAME: ptr nofree readnone align 16 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[P:%.*]] = tail call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef -4) #[[ATTR4]] ; CHECK-NEXT: ret ptr [[P]] ; %p = tail call align 16 ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -4) ret ptr %p }