Skip to content

Commit 31009f0

Browse files
committed
[CodeGen][AArch64] Ensure isSExtCheaperThanZExt returns true for negative constants
When we know the value we're extending is a negative constant then it makes sense to use SIGN_EXTEND because this may improve code quality in some cases, particularly when doing a constant splat of an unpacked vector type. For example, for SVE when splatting the value -1 into all elements of a vector of type <vscale x 2 x i32> the element type will get promoted from i32 -> i64. In this case we want the splat value to sign-extend from (i32 -1) -> (i64 -1), whereas currently it zero-extends from (i32 -1) -> (i64 0xFFFFFFFF). Sign-extending the constant means we can use a single mov immediate instruction. New tests added here: CodeGen/AArch64/sve-vector-splat.ll I believe we see some code quality improvements in these existing tests too: CodeGen/AArch64/dag-numsignbits.ll CodeGen/AArch64/reduce-and.ll CodeGen/AArch64/unfold-masked-merge-vector-variablemask.ll The apparent regressions in CodeGen/AArch64/fast-isel-cmp-vec.ll only occur because the test disables codegen prepare and branch folding. Differential Revision: https://reviews.llvm.org/D114357
1 parent 7ce48be commit 31009f0

21 files changed

+60
-80
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,9 +2645,9 @@ class TargetLoweringBase {
26452645
getApproximateEVTForLLT(ToTy, DL, Ctx));
26462646
}
26472647

2648-
/// Return true if sign-extension from FromTy to ToTy is cheaper than
2649-
/// zero-extension.
2650-
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const {
2648+
/// Return true if sign-extension of value \p V from FromTy to ToTy is
2649+
/// cheaper than zero-extension, where \p V can be SDValue() if unknown.
2650+
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy, SDValue V) const {
26512651
return false;
26522652
}
26532653

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7004,7 +7004,7 @@ bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
70047004
// matching the argument extension instead.
70057005
Instruction::CastOps ExtType = Instruction::ZExt;
70067006
// Some targets prefer SExt over ZExt.
7007-
if (TLI->isSExtCheaperThanZExt(OldVT, RegType))
7007+
if (TLI->isSExtCheaperThanZExt(OldVT, RegType, SDValue()))
70087008
ExtType = Instruction::SExt;
70097009

70107010
if (auto *Arg = dyn_cast<Argument>(Cond)) {

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1704,7 +1704,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &LHS, SDValue &RHS,
17041704
SDValue OpL = GetPromotedInteger(LHS);
17051705
SDValue OpR = GetPromotedInteger(RHS);
17061706

1707-
if (TLI.isSExtCheaperThanZExt(LHS.getValueType(), OpL.getValueType())) {
1707+
if (TLI.isSExtCheaperThanZExt(LHS.getValueType(), OpL.getValueType(), LHS)) {
17081708
// The target would prefer to promote the comparison operand with sign
17091709
// extension. Honor that unless the promoted values are already zero
17101710
// extended.

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
283283
EVT OldVT = Op.getValueType();
284284
SDLoc DL(Op);
285285
Op = GetPromotedInteger(Op);
286-
if (TLI.isSExtCheaperThanZExt(OldVT, Op.getValueType()))
286+
if (TLI.isSExtCheaperThanZExt(OldVT, Op.getValueType(), Op))
287287
return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Op.getValueType(), Op,
288288
DAG.getValueType(OldVT));
289289
return DAG.getZeroExtendInReg(Op, DL, OldVT);

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4767,7 +4767,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
47674767
C->isTargetOpcode(), C->isOpaque());
47684768
case ISD::ANY_EXTEND:
47694769
// Some targets like RISCV prefer to sign extend some types.
4770-
if (TLI->isSExtCheaperThanZExt(Operand.getValueType(), VT))
4770+
if (TLI->isSExtCheaperThanZExt(Operand.getValueType(), VT, Operand))
47714771
return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), DL, VT,
47724772
C->isTargetOpcode(), C->isOpaque());
47734773
return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT,

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3844,7 +3844,7 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
38443844
} else if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
38453845
(Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
38463846
!isSExtCheaperThanZExt(cast<VTSDNode>(N0.getOperand(1))->getVT(),
3847-
OpVT)) {
3847+
OpVT, N0.getOperand(1))) {
38483848
EVT ExtSrcTy = cast<VTSDNode>(N0.getOperand(1))->getVT();
38493849
unsigned ExtSrcTyBits = ExtSrcTy.getSizeInBits();
38503850
EVT ExtDstTy = N0.getValueType();

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,14 @@ class AArch64TargetLowering : public TargetLowering {
11381138

11391139
bool isConstantUnsignedBitfieldExtractLegal(unsigned Opc, LLT Ty1,
11401140
LLT Ty2) const override;
1141+
1142+
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT, SDValue V) const override {
1143+
if (!V)
1144+
return false;
1145+
if (ConstantSDNode *C = isConstOrConstSplat(V))
1146+
return C->getAPIntValue().isNegative();
1147+
return false;
1148+
}
11411149
};
11421150

11431151
namespace AArch64 {

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,8 @@ bool RISCVTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
11981198
return TargetLowering::isZExtFree(Val, VT2);
11991199
}
12001200

1201-
bool RISCVTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const {
1201+
bool RISCVTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT,
1202+
SDValue V) const {
12021203
return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
12031204
}
12041205

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ class RISCVTargetLowering : public TargetLowering {
326326
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
327327
bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
328328
bool isZExtFree(SDValue Val, EVT VT2) const override;
329-
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
329+
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT, SDValue V) const override;
330330
bool isCheapToSpeculateCttz() const override;
331331
bool isCheapToSpeculateCtlz() const override;
332332
bool hasAndNotCompare(SDValue Y) const override;

llvm/test/CodeGen/AArch64/arm64-vshuffle.ll

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,8 @@ entry:
1414
ret <8 x i1> %Shuff
1515
}
1616

17-
; CHECK: lCPI1_0:
18-
; CHECK: .byte 0 ; 0x0
19-
; CHECK: .byte 0 ; 0x0
20-
; CHECK: .byte 0 ; 0x0
21-
; CHECK: .byte 0 ; 0x0
22-
; CHECK: .byte 1 ; 0x1
23-
; CHECK: .byte 0 ; 0x0
24-
; CHECK: .byte 0 ; 0x0
25-
; CHECK: .byte 0 ; 0x0
2617
; CHECK: test2
27-
; CHECK: adrp x[[REG2:[0-9]+]], lCPI1_0@PAGE
28-
; CHECK: ldr d[[REG1:[0-9]+]], [x[[REG2]], lCPI1_0@PAGEOFF]
18+
; CHECK: movi d{{[0-9]+}}, #0x0000ff00000000
2919
define <8 x i1>@test2() {
3020
bb:
3121
%Shuff = shufflevector <8 x i1> zeroinitializer,
@@ -36,7 +26,7 @@ bb:
3626
}
3727

3828
; CHECK: test3
39-
; CHECK: movi.4s v{{[0-9]+}}, #1
29+
; CHECK: movi.2d v{{[0-9]+}}, #0x0000ff000000ff
4030
define <16 x i1> @test3(i1* %ptr, i32 %v) {
4131
bb:
4232
%Shuff = shufflevector <16 x i1> <i1 0, i1 1, i1 1, i1 0, i1 0, i1 1, i1 0, i1 0, i1 0, i1 1, i1 1, i1 0, i1 0, i1 1, i1 0, i1 0>, <16 x i1> undef,
@@ -45,11 +35,13 @@ bb:
4535
i32 14, i32 0>
4636
ret <16 x i1> %Shuff
4737
}
38+
39+
4840
; CHECK: lCPI3_0:
4941
; CHECK: .byte 0 ; 0x0
5042
; CHECK: .byte 0 ; 0x0
5143
; CHECK: .byte 0 ; 0x0
52-
; CHECK: .byte 1 ; 0x1
44+
; CHECK: .byte 255 ; 0xff
5345
; CHECK: .byte 0 ; 0x0
5446
; CHECK: .byte 0 ; 0x0
5547
; CHECK: .byte 0 ; 0x0

0 commit comments

Comments
 (0)