Skip to content

Commit f6315a9

Browse files
authored
[AArch64][LoopIdiom] Disable LoopIdiomTransform when NoImplicitFloat is present (#87677)
This behavior is aligned with both LoopVectorizer and SLPVectorizer.
1 parent 4d6e67f commit f6315a9

File tree

2 files changed

+106
-4
lines changed

2 files changed

+106
-4
lines changed

llvm/lib/Target/AArch64/AArch64LoopIdiomTransform.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,23 @@ AArch64LoopIdiomTransformPass::run(Loop &L, LoopAnalysisManager &AM,
190190
bool AArch64LoopIdiomTransform::run(Loop *L) {
191191
CurLoop = L;
192192

193-
if (DisableAll || L->getHeader()->getParent()->hasOptSize())
193+
Function &F = *L->getHeader()->getParent();
194+
if (DisableAll || F.hasOptSize())
194195
return false;
195196

197+
if (F.hasFnAttribute(Attribute::NoImplicitFloat)) {
198+
LLVM_DEBUG(dbgs() << DEBUG_TYPE << " is disabled on " << F.getName()
199+
<< " due to its NoImplicitFloat attribute");
200+
return false;
201+
}
202+
196203
// If the loop could not be converted to canonical form, it must have an
197204
// indirectbr in it, just give up.
198205
if (!L->getLoopPreheader())
199206
return false;
200207

201-
LLVM_DEBUG(dbgs() << DEBUG_TYPE " Scanning: F["
202-
<< CurLoop->getHeader()->getParent()->getName()
203-
<< "] Loop %" << CurLoop->getHeader()->getName() << "\n");
208+
LLVM_DEBUG(dbgs() << DEBUG_TYPE " Scanning: F[" << F.getName() << "] Loop %"
209+
<< CurLoop->getHeader()->getName() << "\n");
204210

205211
return recognizeByteCompare();
206212
}

llvm/test/Transforms/LoopIdiom/AArch64/byte-compare-index.ll

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,3 +2090,99 @@ while.end:
20902090
ret i32 %res
20912091
}
20922092

2093+
; The optimization should be disabled when noimplicitfloat is present.
2094+
define i32 @no_implicit_float(ptr %a, ptr %b, i32 %len, i32 %extra, i32 %n) noimplicitfloat {
2095+
; CHECK-LABEL: define i32 @no_implicit_float(
2096+
; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {
2097+
; CHECK-NEXT: entry:
2098+
; CHECK-NEXT: br label [[WHILE_COND:%.*]]
2099+
; CHECK: while.cond:
2100+
; CHECK-NEXT: [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2101+
; CHECK-NEXT: [[INC]] = add i32 [[LEN_ADDR]], 1
2102+
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2103+
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2104+
; CHECK: while.body:
2105+
; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2106+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2107+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2108+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2109+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2110+
; CHECK-NEXT: [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2111+
; CHECK-NEXT: br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2112+
; CHECK: while.end:
2113+
; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2114+
; CHECK-NEXT: [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2115+
; CHECK-NEXT: [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2116+
; CHECK-NEXT: ret i32 [[RES]]
2117+
;
2118+
; LOOP-DEL-LABEL: define i32 @no_implicit_float(
2119+
; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {
2120+
; LOOP-DEL-NEXT: entry:
2121+
; LOOP-DEL-NEXT: br label [[WHILE_COND:%.*]]
2122+
; LOOP-DEL: while.cond:
2123+
; LOOP-DEL-NEXT: [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2124+
; LOOP-DEL-NEXT: [[INC]] = add i32 [[LEN_ADDR]], 1
2125+
; LOOP-DEL-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2126+
; LOOP-DEL-NEXT: br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2127+
; LOOP-DEL: while.body:
2128+
; LOOP-DEL-NEXT: [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2129+
; LOOP-DEL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2130+
; LOOP-DEL-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2131+
; LOOP-DEL-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2132+
; LOOP-DEL-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2133+
; LOOP-DEL-NEXT: [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2134+
; LOOP-DEL-NEXT: br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2135+
; LOOP-DEL: while.end:
2136+
; LOOP-DEL-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2137+
; LOOP-DEL-NEXT: [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2138+
; LOOP-DEL-NEXT: [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2139+
; LOOP-DEL-NEXT: ret i32 [[RES]]
2140+
;
2141+
; NO-TRANSFORM-LABEL: define i32 @no_implicit_float(
2142+
; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR1:[0-9]+]] {
2143+
; NO-TRANSFORM-NEXT: entry:
2144+
; NO-TRANSFORM-NEXT: br label [[WHILE_COND:%.*]]
2145+
; NO-TRANSFORM: while.cond:
2146+
; NO-TRANSFORM-NEXT: [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2147+
; NO-TRANSFORM-NEXT: [[INC]] = add i32 [[LEN_ADDR]], 1
2148+
; NO-TRANSFORM-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2149+
; NO-TRANSFORM-NEXT: br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2150+
; NO-TRANSFORM: while.body:
2151+
; NO-TRANSFORM-NEXT: [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2152+
; NO-TRANSFORM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2153+
; NO-TRANSFORM-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2154+
; NO-TRANSFORM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2155+
; NO-TRANSFORM-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2156+
; NO-TRANSFORM-NEXT: [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2157+
; NO-TRANSFORM-NEXT: br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2158+
; NO-TRANSFORM: while.end:
2159+
; NO-TRANSFORM-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2160+
; NO-TRANSFORM-NEXT: [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2161+
; NO-TRANSFORM-NEXT: [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2162+
; NO-TRANSFORM-NEXT: ret i32 [[RES]]
2163+
;
2164+
entry:
2165+
br label %while.cond
2166+
2167+
while.cond:
2168+
%len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
2169+
%inc = add i32 %len.addr, 1
2170+
%cmp.not = icmp eq i32 %inc, %n
2171+
br i1 %cmp.not, label %while.end, label %while.body
2172+
2173+
while.body:
2174+
%idxprom = zext i32 %inc to i64
2175+
%arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
2176+
%0 = load i8, ptr %arrayidx
2177+
%arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
2178+
%1 = load i8, ptr %arrayidx2
2179+
%cmp.not2 = icmp eq i8 %0, %1
2180+
br i1 %cmp.not2, label %while.cond, label %while.end
2181+
2182+
while.end:
2183+
%inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
2184+
%extra.phi = phi i32 [ %extra, %while.body ], [ %extra, %while.cond ]
2185+
%res = add i32 %inc.lcssa, %extra.phi
2186+
ret i32 %res
2187+
}
2188+

0 commit comments

Comments
 (0)