| ; 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 |
| } |