Skip to content

Commit b6cda33

Browse files
authored
[Loads] Also consider getPointerAlignment when checking assumptions. (#120916)
Also use getPointerAlignment when trying to use alignment and dereferenceable assumptions. This catches cases where dereferencable is known via the assumption but alignment is known via getPointerAlignment (e.g. via argument attribute or align of 1) PR: #120916
1 parent a6b7181 commit b6cda33

File tree

2 files changed

+12
-44
lines changed

2 files changed

+12
-44
lines changed

llvm/lib/Analysis/Loads.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ static bool isDereferenceableAndAlignedPointer(
170170

171171
if (CtxI) {
172172
/// Look through assumes to see if both dereferencability and alignment can
173-
/// be provent by an assume
173+
/// be proven by an assume if needed.
174174
RetainedKnowledge AlignRK;
175175
RetainedKnowledge DerefRK;
176+
bool IsAligned = V->getPointerAlignment(DL) >= Alignment;
176177
if (getKnowledgeForValue(
177178
V, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
178179
[&](RetainedKnowledge RK, Instruction *Assume, auto) {
@@ -182,7 +183,8 @@ static bool isDereferenceableAndAlignedPointer(
182183
AlignRK = std::max(AlignRK, RK);
183184
if (RK.AttrKind == Attribute::Dereferenceable)
184185
DerefRK = std::max(DerefRK, RK);
185-
if (AlignRK && DerefRK && AlignRK.ArgValue >= Alignment.value() &&
186+
IsAligned |= AlignRK && AlignRK.ArgValue >= Alignment.value();
187+
if (IsAligned && DerefRK &&
186188
DerefRK.ArgValue >= Size.getZExtValue())
187189
return true; // We have found what we needed so we stop looking
188190
return false; // Other assumes may have better information. so

llvm/test/Transforms/LoopVectorize/dereferenceable-info-from-assumption-constant-size.ll

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ exit:
104104
ret void
105105
}
106106

107-
define void @deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) {
108-
; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
107+
define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) {
108+
; CHECK-LABEL: define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
109109
; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) {
110110
; CHECK-NEXT: [[ENTRY:.*]]:
111111
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ]
@@ -899,32 +899,15 @@ define void @deref_assumption_in_preheader_constant_trip_count_align_1(ptr noali
899899
; CHECK: [[VECTOR_PH]]:
900900
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
901901
; CHECK: [[VECTOR_BODY]]:
902-
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
902+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
903903
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
904904
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
905905
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
906906
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
907907
; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
908-
; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
909-
; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
910-
; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
911-
; CHECK: [[PRED_LOAD_IF]]:
912908
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
913-
; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 1
914-
; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0
915-
; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
916-
; CHECK: [[PRED_LOAD_CONTINUE]]:
917-
; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ]
918-
; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
919-
; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
920-
; CHECK: [[PRED_LOAD_IF1]]:
921-
; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1
922-
; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]]
923-
; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 1
924-
; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1
925-
; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
926-
; CHECK: [[PRED_LOAD_CONTINUE2]]:
927-
; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
909+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP6]], i32 0
910+
; CHECK-NEXT: [[TMP15:%.*]] = load <2 x i32>, ptr [[TMP5]], align 1
928911
; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
929912
; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
930913
; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0
@@ -1168,32 +1151,15 @@ define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via
11681151
; CHECK: [[VECTOR_PH]]:
11691152
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
11701153
; CHECK: [[VECTOR_BODY]]:
1171-
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
1154+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
11721155
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
11731156
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
11741157
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
11751158
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
11761159
; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1177-
; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1178-
; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1179-
; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1180-
; CHECK: [[PRED_LOAD_IF]]:
11811160
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
1182-
; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4
1183-
; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0
1184-
; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1185-
; CHECK: [[PRED_LOAD_CONTINUE]]:
1186-
; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ]
1187-
; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1188-
; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1189-
; CHECK: [[PRED_LOAD_IF1]]:
1190-
; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1
1191-
; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]]
1192-
; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4
1193-
; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1
1194-
; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1195-
; CHECK: [[PRED_LOAD_CONTINUE2]]:
1196-
; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
1161+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP6]], i32 0
1162+
; CHECK-NEXT: [[TMP15:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4
11971163
; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
11981164
; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
11991165
; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0

0 commit comments

Comments
 (0)