Skip to content

Commit 99c8d49

Browse files
author
git apple-llvm automerger
committed
Merge commit '580310ff0c57' from llvm.org/master into apple/master
2 parents 9160eeb + 580310f commit 99c8d49

File tree

4 files changed

+77
-13
lines changed

4 files changed

+77
-13
lines changed

llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,21 +1304,39 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
13041304
if (getParser().parseExpression(Expr))
13051305
return MatchOperand_NoMatch;
13061306

1307+
auto isOutOfRangeConstant = [&](const MCExpr *E) -> bool {
1308+
if (auto *CE = dyn_cast<MCConstantExpr>(E)) {
1309+
int64_t Value = CE->getValue();
1310+
if ((Value & 1) || Value < MinVal || Value > MaxVal)
1311+
return true;
1312+
}
1313+
return false;
1314+
};
1315+
13071316
// For consistency with the GNU assembler, treat immediates as offsets
13081317
// from ".".
13091318
if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1310-
int64_t Value = CE->getValue();
1311-
if ((Value & 1) || Value < MinVal || Value > MaxVal) {
1319+
if (isOutOfRangeConstant(CE)) {
13121320
Error(StartLoc, "offset out of range");
13131321
return MatchOperand_ParseFail;
13141322
}
1323+
int64_t Value = CE->getValue();
13151324
MCSymbol *Sym = Ctx.createTempSymbol();
13161325
Out.EmitLabel(Sym);
13171326
const MCExpr *Base = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
13181327
Ctx);
13191328
Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx);
13201329
}
13211330

1331+
// For consistency with the GNU assembler, conservatively assume that a
1332+
// constant offset must by itself be within the given size range.
1333+
if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1334+
if (isOutOfRangeConstant(BE->getLHS()) ||
1335+
isOutOfRangeConstant(BE->getRHS())) {
1336+
Error(StartLoc, "offset out of range");
1337+
return MatchOperand_ParseFail;
1338+
}
1339+
13221340
// Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
13231341
const MCExpr *Sym = nullptr;
13241342
if (AllowTLS && getLexer().is(AsmToken::Colon)) {

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,17 +2828,26 @@ SDValue SystemZTargetLowering::lowerGlobalAddress(GlobalAddressSDNode *Node,
28282828

28292829
SDValue Result;
28302830
if (Subtarget.isPC32DBLSymbol(GV, CM)) {
2831-
// Assign anchors at 1<<12 byte boundaries.
2832-
uint64_t Anchor = Offset & ~uint64_t(0xfff);
2833-
Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor);
2834-
Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2835-
2836-
// The offset can be folded into the address if it is aligned to a halfword.
2837-
Offset -= Anchor;
2838-
if (Offset != 0 && (Offset & 1) == 0) {
2839-
SDValue Full = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor + Offset);
2840-
Result = DAG.getNode(SystemZISD::PCREL_OFFSET, DL, PtrVT, Full, Result);
2841-
Offset = 0;
2831+
if (isInt<32>(Offset)) {
2832+
// Assign anchors at 1<<12 byte boundaries.
2833+
uint64_t Anchor = Offset & ~uint64_t(0xfff);
2834+
Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor);
2835+
Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2836+
2837+
// The offset can be folded into the address if it is aligned to a
2838+
// halfword.
2839+
Offset -= Anchor;
2840+
if (Offset != 0 && (Offset & 1) == 0) {
2841+
SDValue Full =
2842+
DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor + Offset);
2843+
Result = DAG.getNode(SystemZISD::PCREL_OFFSET, DL, PtrVT, Full, Result);
2844+
Offset = 0;
2845+
}
2846+
} else {
2847+
// Conservatively load a constant offset greater than 32 bits into a
2848+
// register below.
2849+
Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT);
2850+
Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
28422851
}
28432852
} else {
28442853
Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, SystemZII::MO_GOT);

llvm/test/CodeGen/SystemZ/la-05.ll

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; Test that a huge address offset is loaded into a register and then added
2+
; separately.
3+
;
4+
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5+
6+
@a = common dso_local global i32 0, align 4
7+
8+
define i64 @f1() {
9+
; CHECK-LABEL: f1:
10+
; CHECK: llihl %r0, 829
11+
; CHECK: oilf %r0, 4294966308
12+
; CHECK: larl %r2, a
13+
; CHECK: agr %r2, %r0
14+
; CHECK: br %r14
15+
ret i64 add (i64 ptrtoint (i32* @a to i64), i64 3564822854692)
16+
}
17+
18+
define signext i32 @f2() {
19+
; CHECK-LABEL: f2:
20+
; CHECK: llihl %r0, 829
21+
; CHECK: oilf %r0, 4294966308
22+
; CHECK: larl %r1, a
23+
; CHECK: agr %r1, %r0
24+
; CHECK: lgf %r2, 0(%r1)
25+
; CHECK: br %r14
26+
entry:
27+
%0 = load i32, i32* inttoptr (i64 add (i64 ptrtoint (i32* @a to i64),
28+
i64 3564822854692) to i32*)
29+
ret i32 %0
30+
}
31+

llvm/test/MC/SystemZ/insn-bad.s

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,11 +3104,14 @@
31043104
#CHECK: larl %r0, 1
31053105
#CHECK: error: offset out of range
31063106
#CHECK: larl %r0, 0x100000000
3107+
#CHECK: error: offset out of range
3108+
#CHECK: larl %r1, __unnamed_1+3564822854692
31073109

31083110
larl %r0, -0x1000000002
31093111
larl %r0, -1
31103112
larl %r0, 1
31113113
larl %r0, 0x100000000
3114+
larl %r1, __unnamed_1+3564822854692
31123115

31133116
#CHECK: error: invalid use of indexed addressing
31143117
#CHECK: lasp 160(%r1,%r15),160(%r15)
@@ -3840,11 +3843,14 @@
38403843
#CHECK: lrl %r0, 1
38413844
#CHECK: error: offset out of range
38423845
#CHECK: lrl %r0, 0x100000000
3846+
#CHECK: error: offset out of range
3847+
#CHECK: lrl %r1, __unnamed_1+3564822854692
38433848

38443849
lrl %r0, -0x1000000002
38453850
lrl %r0, -1
38463851
lrl %r0, 1
38473852
lrl %r0, 0x100000000
3853+
lrl %r1, __unnamed_1+3564822854692
38483854

38493855
#CHECK: error: invalid operand
38503856
#CHECK: lrv %r0, -524289

0 commit comments

Comments
 (0)