[llvm] [Attributor] Propagate alignment through ptrmask (PR #150158)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 28 00:30:06 PDT 2025
================
@@ -0,0 +1,101 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=attributor -S < %s | FileCheck %s
+
+define float @align_ptrmask_back_no_prop(ptr align 2 %x, i1 %cmp1, i1 %cmp2) {
+; CHECK-LABEL: define float @align_ptrmask_back_no_prop(
+; CHECK-SAME: ptr nofree readonly 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 align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0:![0-9]+]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ %sel = select i1 %cmp1, i64 -32, i64 -8
+ %sel1 = select i1 %cmp2, i64 %sel, i64 -16
+ %p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
+ %res = load float, ptr %p, align 8
+ ret float %res
+}
+
+define float @align_ptrmask_back_prop(ptr align 2 %x, i1 %cmp1, i1 %cmp2) {
+; CHECK-LABEL: define float @align_ptrmask_back_prop(
+; CHECK-SAME: ptr nofree readonly 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 align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2]]
+; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 16, !invariant.load [[META0]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ %sel = select i1 %cmp1, i64 -32, i64 -8
+ %sel1 = select i1 %cmp2, i64 %sel, i64 -16
+ %p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
+ %res = load float, ptr %p, align 16
+ ret float %res
+}
+
+define float @align_ptrmask_forward_mask(ptr align 2 %x, i1 %cmp1, i1 %cmp2) {
+; CHECK-LABEL: define float @align_ptrmask_forward_mask(
+; CHECK-SAME: ptr nofree readonly align 2 [[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 align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2]]
+; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ %sel = select i1 %cmp1, i64 -32, i64 -8
+ %sel1 = select i1 %cmp2, i64 %sel, i64 -16
+ %p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
+ %res = load float, ptr %p, align 4
+ ret float %res
+}
+
+define float @align_ptrmask_forward_ptr(ptr align 16 %x, i1 %cmp1, i1 %cmp2) {
+; CHECK-LABEL: define float @align_ptrmask_forward_ptr(
+; CHECK-SAME: ptr nofree readonly 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 align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2]]
+; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 16, !invariant.load [[META0]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ %sel = select i1 %cmp1, i64 -32, i64 -8
+ %sel1 = select i1 %cmp2, i64 %sel, i64 -16
+ %p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
+ %res = load float, ptr %p, align 4
+ ret float %res
+}
+
+define float @align_ptrmask_forward_nonconst_mask(ptr align 8 %x, i64 %y, i1 %cmp1, i1 %cmp2) {
+; CHECK-LABEL: define float @align_ptrmask_forward_nonconst_mask(
+; CHECK-SAME: ptr nofree readonly 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 align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 [[SEL1]]) #[[ATTR2]]
+; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ %sel = select i1 %cmp1, i64 -32, i64 %y
+ %sel1 = select i1 %cmp2, i64 %sel, i64 -16
+ %p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
+ %res = load float, ptr %p, align 4
+ ret float %res
+}
+
+define float @align_ptrmask_back_nonconst_mask(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) {
+; CHECK-LABEL: define float @align_ptrmask_back_nonconst_mask(
+; CHECK-SAME: ptr nofree readonly 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 align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 [[SEL1]]) #[[ATTR2]]
+; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0]]
+; CHECK-NEXT: ret float [[RES]]
+;
+ %sel = select i1 %cmp1, i64 -32, i64 %y
+ %sel1 = select i1 %cmp2, i64 %sel, i64 -16
+ %p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
+ %res = load float, ptr %p, align 8
+ ret float %res
+}
+;.
----------------
arsenm wrote:
extractelement can propagate alignment, whether or not it does currently is another question
https://github.com/llvm/llvm-project/pull/150158
More information about the llvm-commits
mailing list