Skip to content

Commit eb122f2

Browse files
committedJul 9, 2015
Fix shift legalization and lowering for big constants.
Summary: If shift amount is a constant value > 64 bit it is handled incorrectly during type legalization and X86 lowering. This patch the type of shift amount argument in function DAGTypeLegalizer::ExpandShiftByConstant from unsigned to APInt. Reviewers: nadav, majnemer, sanjoy, RKSimon Subscribers: RKSimon, llvm-commits Differential Revision: http://reviews.llvm.org/D10767 llvm-svn: 241790
1 parent 45a5bfe commit eb122f2

File tree

4 files changed

+62
-19
lines changed

4 files changed

+62
-19
lines changed
 

‎llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

+15-16
Original file line numberDiff line numberDiff line change
@@ -1358,9 +1358,9 @@ std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
13581358
return ExpandChainLibCall(LC, Node, false);
13591359
}
13601360

1361-
/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
1361+
/// N is a shift by a value that needs to be expanded,
13621362
/// and the shift amount is a constant 'Amt'. Expand the operation.
1363-
void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
1363+
void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, const APInt &Amt,
13641364
SDValue &Lo, SDValue &Hi) {
13651365
SDLoc DL(N);
13661366
// Expand the incoming operand to be shifted, so that we have its parts
@@ -1381,12 +1381,12 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
13811381
EVT ShTy = N->getOperand(1).getValueType();
13821382

13831383
if (N->getOpcode() == ISD::SHL) {
1384-
if (Amt > VTBits) {
1384+
if (Amt.ugt(VTBits)) {
13851385
Lo = Hi = DAG.getConstant(0, DL, NVT);
1386-
} else if (Amt > NVTBits) {
1386+
} else if (Amt.ugt(NVTBits)) {
13871387
Lo = DAG.getConstant(0, DL, NVT);
13881388
Hi = DAG.getNode(ISD::SHL, DL,
1389-
NVT, InL, DAG.getConstant(Amt - NVTBits, DL, ShTy));
1389+
NVT, InL, DAG.getConstant(-Amt + NVTBits, DL, ShTy));
13901390
} else if (Amt == NVTBits) {
13911391
Lo = DAG.getConstant(0, DL, NVT);
13921392
Hi = InL;
@@ -1405,16 +1405,15 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
14051405
DAG.getNode(ISD::SHL, DL, NVT, InH,
14061406
DAG.getConstant(Amt, DL, ShTy)),
14071407
DAG.getNode(ISD::SRL, DL, NVT, InL,
1408-
DAG.getConstant(NVTBits - Amt, DL, ShTy)));
1408+
DAG.getConstant(-Amt + NVTBits, DL, ShTy)));
14091409
}
14101410
return;
14111411
}
14121412

14131413
if (N->getOpcode() == ISD::SRL) {
1414-
if (Amt > VTBits) {
1415-
Lo = DAG.getConstant(0, DL, NVT);
1416-
Hi = DAG.getConstant(0, DL, NVT);
1417-
} else if (Amt > NVTBits) {
1414+
if (Amt.ugt(VTBits)) {
1415+
Lo = Hi = DAG.getConstant(0, DL, NVT);
1416+
} else if (Amt.ugt(NVTBits)) {
14181417
Lo = DAG.getNode(ISD::SRL, DL,
14191418
NVT, InH, DAG.getConstant(Amt - NVTBits, DL, ShTy));
14201419
Hi = DAG.getConstant(0, DL, NVT);
@@ -1426,19 +1425,19 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
14261425
DAG.getNode(ISD::SRL, DL, NVT, InL,
14271426
DAG.getConstant(Amt, DL, ShTy)),
14281427
DAG.getNode(ISD::SHL, DL, NVT, InH,
1429-
DAG.getConstant(NVTBits - Amt, DL, ShTy)));
1428+
DAG.getConstant(-Amt + NVTBits, DL, ShTy)));
14301429
Hi = DAG.getNode(ISD::SRL, DL, NVT, InH, DAG.getConstant(Amt, DL, ShTy));
14311430
}
14321431
return;
14331432
}
14341433

14351434
assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
1436-
if (Amt > VTBits) {
1435+
if (Amt.ugt(VTBits)) {
14371436
Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
14381437
DAG.getConstant(NVTBits - 1, DL, ShTy));
1439-
} else if (Amt > NVTBits) {
1438+
} else if (Amt.ugt(NVTBits)) {
14401439
Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
1441-
DAG.getConstant(Amt-NVTBits, DL, ShTy));
1440+
DAG.getConstant(Amt - NVTBits, DL, ShTy));
14421441
Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
14431442
DAG.getConstant(NVTBits - 1, DL, ShTy));
14441443
} else if (Amt == NVTBits) {
@@ -1450,7 +1449,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
14501449
DAG.getNode(ISD::SRL, DL, NVT, InL,
14511450
DAG.getConstant(Amt, DL, ShTy)),
14521451
DAG.getNode(ISD::SHL, DL, NVT, InH,
1453-
DAG.getConstant(NVTBits - Amt, DL, ShTy)));
1452+
DAG.getConstant(-Amt + NVTBits, DL, ShTy)));
14541453
Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, DAG.getConstant(Amt, DL, ShTy));
14551454
}
14561455
}
@@ -2178,7 +2177,7 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
21782177
// If we can emit an efficient shift operation, do so now. Check to see if
21792178
// the RHS is a constant.
21802179
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
2181-
return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi);
2180+
return ExpandShiftByConstant(N, CN->getAPIntValue(), Lo, Hi);
21822181

21832182
// If we can determine that the high bit of the shift is zero or one, even if
21842183
// the low bits are variable, emit this shift in an optimized form.

‎llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
167167
SDValue GetVectorElementPointer(SDValue VecPtr, EVT EltVT, SDValue Index);
168168
SDValue JoinIntegers(SDValue Lo, SDValue Hi);
169169
SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned);
170-
170+
171171
std::pair<SDValue, SDValue> ExpandChainLibCall(RTLIB::Libcall LC,
172172
SDNode *Node, bool isSigned);
173173
std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node);
@@ -347,7 +347,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
347347

348348
void ExpandIntRes_ATOMIC_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi);
349349

350-
void ExpandShiftByConstant(SDNode *N, unsigned Amt,
350+
void ExpandShiftByConstant(SDNode *N, const APInt &Amt,
351351
SDValue &Lo, SDValue &Hi);
352352
bool ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi);
353353
bool ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi);

‎llvm/lib/Target/X86/X86ISelLowering.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -23167,7 +23167,7 @@ static SDValue PerformSHLCombine(SDNode *N, SelectionDAG &DAG) {
2316723167
// We shift all of the values by one. In many cases we do not have
2316823168
// hardware support for this operation. This is better expressed as an ADD
2316923169
// of two values.
23170-
if (N1SplatC->getZExtValue() == 1)
23170+
if (N1SplatC->getAPIntValue() == 1)
2317123171
return DAG.getNode(ISD::ADD, SDLoc(N), VT, N0, N0);
2317223172
}
2317323173

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; RUN: llc < %s -march=x86-64 | FileCheck %s
2+
3+
define <2 x i256> @test_shl(<2 x i256> %In) {
4+
%Amt = insertelement <2 x i256> undef, i256 -1, i32 0
5+
%Out = shl <2 x i256> %In, %Amt
6+
ret <2 x i256> %Out
7+
8+
; CHECK-LABEL: test_shl
9+
; CHECK: movq $0
10+
; CHECK-NEXT: movq $0
11+
; CHECK-NEXT: movq $0
12+
; CHECK-NEXT: movq $0
13+
; CHECK-NEXT: movq $0
14+
; CHECK-NEXT: movq $0
15+
; CHECK-NEXT: movq $0
16+
; CHECK-NEXT: movq $0
17+
; CHECK: retq
18+
}
19+
20+
define <2 x i256> @test_srl(<2 x i256> %In) {
21+
%Amt = insertelement <2 x i256> undef, i256 -1, i32 0
22+
%Out = lshr <2 x i256> %In, %Amt
23+
ret <2 x i256> %Out
24+
25+
; CHECK-LABEL: test_srl
26+
; CHECK: movq $0
27+
; CHECK-NEXT: movq $0
28+
; CHECK-NEXT: movq $0
29+
; CHECK-NEXT: movq $0
30+
; CHECK-NEXT: movq $0
31+
; CHECK-NEXT: movq $0
32+
; CHECK-NEXT: movq $0
33+
; CHECK-NEXT: movq $0
34+
; CHECK: retq
35+
}
36+
37+
define <2 x i256> @test_sra(<2 x i256> %In) {
38+
%Amt = insertelement <2 x i256> undef, i256 -1, i32 0
39+
%Out = ashr <2 x i256> %In, %Amt
40+
ret <2 x i256> %Out
41+
42+
; CHECK-LABEL: test_sra
43+
; CHECK: sarq $63
44+
}

0 commit comments

Comments
 (0)
Please sign in to comment.