Skip to content

Commit f52123b

Browse files
committed
[AArch64] Fix sext/zext folding in address arithmetic.
We were accidentally folding a sign/zero extend in to address arithmetic in a different BB when the extend wasn't available there. Cross BB fast-isel isn't safe, so restrict this to only when the extend is in the same BB as the use. llvm-svn: 236764
1 parent 841ee9b commit f52123b

File tree

2 files changed

+71
-29
lines changed

2 files changed

+71
-29
lines changed

llvm/lib/Target/AArch64/AArch64FastISel.cpp

+32-29
Original file line numberDiff line numberDiff line change
@@ -664,20 +664,22 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
664664
Addr.setExtendType(AArch64_AM::LSL);
665665

666666
const Value *Src = U->getOperand(0);
667-
if (const auto *I = dyn_cast<Instruction>(Src))
668-
if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB)
669-
Src = I;
670-
671-
// Fold the zext or sext when it won't become a noop.
672-
if (const auto *ZE = dyn_cast<ZExtInst>(Src)) {
673-
if (!isIntExtFree(ZE) && ZE->getOperand(0)->getType()->isIntegerTy(32)) {
674-
Addr.setExtendType(AArch64_AM::UXTW);
675-
Src = ZE->getOperand(0);
676-
}
677-
} else if (const auto *SE = dyn_cast<SExtInst>(Src)) {
678-
if (!isIntExtFree(SE) && SE->getOperand(0)->getType()->isIntegerTy(32)) {
679-
Addr.setExtendType(AArch64_AM::SXTW);
680-
Src = SE->getOperand(0);
667+
if (const auto *I = dyn_cast<Instruction>(Src)) {
668+
if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
669+
// Fold the zext or sext when it won't become a noop.
670+
if (const auto *ZE = dyn_cast<ZExtInst>(I)) {
671+
if (!isIntExtFree(ZE) &&
672+
ZE->getOperand(0)->getType()->isIntegerTy(32)) {
673+
Addr.setExtendType(AArch64_AM::UXTW);
674+
Src = ZE->getOperand(0);
675+
}
676+
} else if (const auto *SE = dyn_cast<SExtInst>(I)) {
677+
if (!isIntExtFree(SE) &&
678+
SE->getOperand(0)->getType()->isIntegerTy(32)) {
679+
Addr.setExtendType(AArch64_AM::SXTW);
680+
Src = SE->getOperand(0);
681+
}
682+
}
681683
}
682684
}
683685

@@ -746,21 +748,22 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
746748
Addr.setExtendType(AArch64_AM::LSL);
747749

748750
const Value *Src = LHS;
749-
if (const auto *I = dyn_cast<Instruction>(Src))
750-
if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB)
751-
Src = I;
752-
753-
754-
// Fold the zext or sext when it won't become a noop.
755-
if (const auto *ZE = dyn_cast<ZExtInst>(Src)) {
756-
if (!isIntExtFree(ZE) && ZE->getOperand(0)->getType()->isIntegerTy(32)) {
757-
Addr.setExtendType(AArch64_AM::UXTW);
758-
Src = ZE->getOperand(0);
759-
}
760-
} else if (const auto *SE = dyn_cast<SExtInst>(Src)) {
761-
if (!isIntExtFree(SE) && SE->getOperand(0)->getType()->isIntegerTy(32)) {
762-
Addr.setExtendType(AArch64_AM::SXTW);
763-
Src = SE->getOperand(0);
751+
if (const auto *I = dyn_cast<Instruction>(Src)) {
752+
if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
753+
// Fold the zext or sext when it won't become a noop.
754+
if (const auto *ZE = dyn_cast<ZExtInst>(I)) {
755+
if (!isIntExtFree(ZE) &&
756+
ZE->getOperand(0)->getType()->isIntegerTy(32)) {
757+
Addr.setExtendType(AArch64_AM::UXTW);
758+
Src = ZE->getOperand(0);
759+
}
760+
} else if (const auto *SE = dyn_cast<SExtInst>(I)) {
761+
if (!isIntExtFree(SE) &&
762+
SE->getOperand(0)->getType()->isIntegerTy(32)) {
763+
Addr.setExtendType(AArch64_AM::SXTW);
764+
Src = SE->getOperand(0);
765+
}
766+
}
764767
}
765768
}
766769

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; RUN: llc %s -o - -O0 -verify-machineinstrs -fast-isel=true | FileCheck %s
2+
3+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
4+
target triple = "arm64-apple-ios8.0.0"
5+
6+
; This test was trying to fold the sext %tmp142 in to the address arithmetic in %sunkaddr1.
7+
; This was incorrect as %.mux isn't available in the last bb.
8+
9+
; CHECK: sxtw [[REG:x[0-9]+]]
10+
; CHECK: strh wzr, {{\[}}[[REG]], {{.*}}, lsl #1]
11+
12+
; Function Attrs: nounwind optsize ssp
13+
define void @EdgeLoop(i32 %dir, i32 %edge, i32 %width, i16* %tmp89, i32 %tmp136, i16 %tmp144) #0 {
14+
bb:
15+
%tmp2 = icmp eq i32 %dir, 0
16+
%.mux = select i1 %tmp2, i32 %width, i32 1
17+
%tmp142 = sext i32 %.mux to i64
18+
%tmp151 = shl nsw i64 %tmp142, 1
19+
%tmp153 = getelementptr inbounds i16, i16* %tmp89, i64 %tmp151
20+
%tmp154 = load i16, i16* %tmp153, align 2
21+
%tmp155 = zext i16 %tmp154 to i32
22+
br i1 %tmp2, label %bb225, label %bb212
23+
24+
bb212: ; preds = %bb
25+
store i16 %tmp144, i16* %tmp89, align 2
26+
ret void
27+
28+
bb225: ; preds = %bb
29+
%tmp248 = trunc i32 %tmp155 to i16
30+
store i16 %tmp248, i16* %tmp89, align 2
31+
%sunkaddr = ptrtoint i16* %tmp89 to i64
32+
%sunkaddr1 = mul i64 %tmp142, 2
33+
%sunkaddr2 = add i64 %sunkaddr, %sunkaddr1
34+
%sunkaddr3 = inttoptr i64 %sunkaddr2 to i16*
35+
store i16 0, i16* %sunkaddr3, align 2
36+
ret void
37+
}
38+
39+
attributes #0 = { nounwind optsize ssp }

0 commit comments

Comments
 (0)