Skip to content

Commit 7ea0c5f

Browse files
author
anoopkg6
committed
- Changes relating to ConstraintInfo for setting flag output CC upper bound
for all backend suuporting flag output operand (X86, AARCH64 and SystemZ). - Remove all changes target specific changes from SelectionDAGBuiler.cpp. - Added getJumpConditionMergingParams for SystemZ for setting cost for merging srl/ipm/cc. - TODO: Handle the cases where simplifyBranchOnICmpChain creates switch table while folding branch on And'd or Or'd chain of icmp instructions.
1 parent fccc70e commit 7ea0c5f

18 files changed

+146
-115
lines changed

clang/include/clang/Basic/TargetInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ class TargetInfo : public TransferrableTargetInfo,
11191119
public:
11201120
ConstraintInfo(StringRef ConstraintStr, StringRef Name)
11211121
: Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
1122-
Name(Name.str()), FlagOutputCCUpperBound(2) {
1122+
Name(Name.str()), FlagOutputCCUpperBound(0) {
11231123
ImmRange.Min = ImmRange.Max = 0;
11241124
ImmRange.isConstrained = false;
11251125
}

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,7 @@ bool AArch64TargetInfo::validateAsmConstraint(
15521552
if (const unsigned Len = matchAsmCCConstraint(Name)) {
15531553
Name += Len - 1;
15541554
Info.setAllowsRegister();
1555+
Info.setFlagOutputCCUpperBound(2);
15551556
return true;
15561557
}
15571558
}

clang/lib/Basic/Targets/SystemZ.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ bool SystemZTargetInfo::validateAsmConstraint(
100100
return true;
101101
case '@':
102102
// CC condition changes.
103-
if (!StringRef("@cc").compare(Name)) {
103+
if (StringRef(Name) == "@cc") {
104104
Name += 2;
105105
Info.setAllowsRegister();
106106
Info.setFlagOutputCCUpperBound(4);

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
120120

121121
std::string convertConstraint(const char *&Constraint) const override {
122122
if (llvm::StringRef(Constraint) == "@cc") {
123-
auto Len = llvm::StringRef("@cc").size();
124-
std::string Converted = std::string("{@cc}");
125-
Constraint += Len - 1;
126-
return Converted;
123+
Constraint += 2;
124+
return std::string("{@cc}");
127125
}
128126
switch (Constraint[0]) {
129127
case 'p': // Keep 'p' constraint.

clang/lib/Basic/Targets/X86.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,7 @@ bool X86TargetInfo::validateAsmConstraint(
15801580
if (auto Len = matchAsmCCConstraint(Name)) {
15811581
Name += Len - 1;
15821582
Info.setAllowsRegister();
1583+
Info.setFlagOutputCCUpperBound(2);
15831584
return true;
15841585
}
15851586
return false;

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,7 +2601,7 @@ EmitAsmStores(CodeGenFunction &CGF, const AsmStmt &S,
26012601
const llvm::ArrayRef<LValue> ResultRegDests,
26022602
const llvm::ArrayRef<QualType> ResultRegQualTys,
26032603
const llvm::BitVector &ResultTypeRequiresCast,
2604-
const llvm::BitVector &ResultRegIsFlagReg) {
2604+
const std::vector<unsigned> &ResultRegIsFlagReg) {
26052605
CGBuilderTy &Builder = CGF.Builder;
26062606
CodeGenModule &CGM = CGF.CGM;
26072607
llvm::LLVMContext &CTX = CGF.getLLVMContext();
@@ -2628,14 +2628,7 @@ EmitAsmStores(CodeGenFunction &CGF, const AsmStmt &S,
26282628
// observed for select_cc on SystemZ unit tests for flag output operands.
26292629
// For some cases for br_cc, generated IR was weird. e.g. switch table
26302630
// for simple simple comparison terms for br_cc.
2631-
StringRef Name;
2632-
if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
2633-
Name = GAS->getOutputName(i);
2634-
TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), Name);
2635-
bool IsValid = CGF.getTarget().validateOutputConstraint(Info);
2636-
(void)IsValid;
2637-
assert(IsValid && "Failed to parse flag output operand constraint");
2638-
unsigned CCUpperBound = Info.getFlagOutputCCUpperBound();
2631+
unsigned CCUpperBound = ResultRegIsFlagReg[i];
26392632
llvm::Constant *CCUpperBoundConst =
26402633
llvm::ConstantInt::get(Tmp->getType(), CCUpperBound);
26412634
llvm::Value *IsBooleanValue =
@@ -2766,7 +2759,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
27662759
std::vector<llvm::Type *> ArgElemTypes;
27672760
std::vector<llvm::Value*> Args;
27682761
llvm::BitVector ResultTypeRequiresCast;
2769-
llvm::BitVector ResultRegIsFlagReg;
2762+
std::vector<unsigned> ResultRegIsFlagReg;
27702763

27712764
// Keep track of inout constraints.
27722765
std::string InOutConstraints;
@@ -2824,8 +2817,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
28242817
ResultRegQualTys.push_back(QTy);
28252818
ResultRegDests.push_back(Dest);
28262819

2827-
bool IsFlagReg = llvm::StringRef(OutputConstraint).starts_with("{@cc");
2828-
ResultRegIsFlagReg.push_back(IsFlagReg);
2820+
ResultRegIsFlagReg.push_back(Info.getFlagOutputCCUpperBound());
28292821

28302822
llvm::Type *Ty = ConvertTypeForMem(QTy);
28312823
const bool RequiresCast = Info.allowsRegister() &&

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5107,9 +5107,6 @@ class TargetLowering : public TargetLoweringBase {
51075107
std::vector<SDValue> &Ops,
51085108
SelectionDAG &DAG) const;
51095109

5110-
// Lower switch statement for flag output operand with SRL/IPM Sequence.
5111-
virtual bool canLowerSRL_IPM_Switch(SDValue Cond) const;
5112-
51135110
// Lower custom output constraints. If invalid, return SDValue().
51145111
virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Glue,
51155112
const SDLoc &DL,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 7 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2837,34 +2837,7 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) {
28372837
Opcode = Instruction::And;
28382838
else if (match(BOp, m_LogicalOr(m_Value(BOp0), m_Value(BOp1))))
28392839
Opcode = Instruction::Or;
2840-
auto &TLI = DAG.getTargetLoweringInfo();
2841-
const auto checkSRLIPM = [&TLI](const SDValue &Op) {
2842-
if (!Op.getNumOperands())
2843-
return false;
2844-
SDValue OpVal = Op.getOperand(0);
2845-
SDNode *N = OpVal.getNode();
2846-
if (N && N->getOpcode() == ISD::SRL)
2847-
return TLI.canLowerSRL_IPM_Switch(OpVal);
2848-
else if (N && OpVal.getNumOperands() &&
2849-
(N->getOpcode() == ISD::AND || N->getOpcode() == ISD::OR)) {
2850-
SDValue OpVal1 = OpVal.getOperand(0);
2851-
SDNode *N1 = OpVal1.getNode();
2852-
if (N1 && N1->getOpcode() == ISD::SRL)
2853-
return TLI.canLowerSRL_IPM_Switch(OpVal1);
2854-
}
2855-
return false;
2856-
};
2857-
// Incoming IR here is straight line code, FindMergedConditions splits
2858-
// condition code sequence across Basic Block. DAGCombiner can't combine
2859-
// across Basic Block. Identify SRL/IPM/CC sequence for SystemZ and avoid
2860-
// transformation in FindMergedConditions.
2861-
bool BrSrlIPM = false;
2862-
if (NodeMap.count(BOp0) && NodeMap[BOp0].getNode()) {
2863-
BrSrlIPM |= checkSRLIPM(getValue(BOp0));
2864-
if (NodeMap.count(BOp1) && NodeMap[BOp1].getNode())
2865-
BrSrlIPM &= checkSRLIPM(getValue(BOp1));
2866-
}
2867-
if (Opcode && !BrSrlIPM &&
2840+
if (Opcode &&
28682841
!(match(BOp0, m_ExtractElt(m_Value(Vec), m_Value())) &&
28692842
match(BOp1, m_ExtractElt(m_Specific(Vec), m_Value()))) &&
28702843
!shouldKeepJumpConditionsTogether(
@@ -12138,36 +12111,19 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond,
1213812111
const APInt &SmallValue = Small.Low->getValue();
1213912112
const APInt &BigValue = Big.Low->getValue();
1214012113

12141-
// Incoming IR is switch table.Identify SRL/IPM/CC sequence for SystemZ
12142-
// and we want to avoid splitting condition code sequence across basic
12143-
// block for cases like (CC == 0) || (CC == 2) || (CC == 3), or
12144-
// (CC == 0) || (CC == 1) ^ (CC == 3), there could potentially be
12145-
// more cases like this.
12146-
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12147-
bool IsSrlIPM = false;
12148-
if (NodeMap.count(Cond) && NodeMap[Cond].getNode())
12149-
IsSrlIPM = TLI.canLowerSRL_IPM_Switch(getValue(Cond));
1215012114
// Check that there is only one bit different.
1215112115
APInt CommonBit = BigValue ^ SmallValue;
12152-
if (CommonBit.isPowerOf2() || IsSrlIPM) {
12116+
if (CommonBit.isPowerOf2()) {
1215312117
SDValue CondLHS = getValue(Cond);
1215412118
EVT VT = CondLHS.getValueType();
1215512119
SDLoc DL = getCurSDLoc();
1215612120
SDValue Cond;
1215712121

12158-
if (CommonBit.isPowerOf2()) {
12159-
SDValue Or = DAG.getNode(ISD::OR, DL, VT, CondLHS,
12160-
DAG.getConstant(CommonBit, DL, VT));
12161-
Cond = DAG.getSetCC(DL, MVT::i1, Or,
12162-
DAG.getConstant(BigValue | SmallValue, DL, VT),
12163-
ISD::SETEQ);
12164-
} else if (IsSrlIPM && BigValue == 3 && SmallValue == 0) {
12165-
SDValue SetCC =
12166-
DAG.getSetCC(DL, MVT::i32, CondLHS,
12167-
DAG.getConstant(SmallValue, DL, VT), ISD::SETEQ);
12168-
Cond = DAG.getSetCC(DL, MVT::i32, SetCC,
12169-
DAG.getConstant(BigValue, DL, VT), ISD::SETEQ);
12170-
}
12122+
SDValue Or = DAG.getNode(ISD::OR, DL, VT, CondLHS,
12123+
DAG.getConstant(CommonBit, DL, VT));
12124+
Cond = DAG.getSetCC(DL, MVT::i1, Or,
12125+
DAG.getConstant(BigValue | SmallValue, DL, VT),
12126+
ISD::SETEQ);
1217112127

1217212128
// Update successor info.
1217312129
// Both Small and Big will jump to Small.BB, so we sum up the

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5576,10 +5576,6 @@ const char *TargetLowering::LowerXConstraint(EVT ConstraintVT) const {
55765576
return nullptr;
55775577
}
55785578

5579-
bool TargetLowering::canLowerSRL_IPM_Switch(SDValue Cond) const {
5580-
return false;
5581-
}
5582-
55835579
SDValue TargetLowering::LowerAsmOutputForConstraint(
55845580
SDValue &Chain, SDValue &Glue, const SDLoc &DL,
55855581
const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const {

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/IR/IntrinsicInst.h"
2525
#include "llvm/IR/Intrinsics.h"
2626
#include "llvm/IR/IntrinsicsS390.h"
27+
#include "llvm/IR/PatternMatch.h"
2728
#include "llvm/Support/CommandLine.h"
2829
#include "llvm/Support/ErrorHandling.h"
2930
#include "llvm/Support/KnownBits.h"
@@ -8694,23 +8695,37 @@ SystemZTargetLowering::combineSELECT_CC_CCIPMMask(SDNode *N,
86948695
return std::nullopt;
86958696
}
86968697

8697-
bool SystemZTargetLowering::canLowerSRL_IPM_Switch(SDValue Cond) const {
8698-
auto *SRL = Cond.getNode();
8699-
if (!SRL || SRL->getOpcode() != ISD::SRL)
8700-
return false;
8701-
auto *SRLCount = dyn_cast<ConstantSDNode>(SRL->getOperand(1));
8702-
if (!SRLCount || SRLCount->getZExtValue() != SystemZ::IPM_CC)
8703-
return false;
8704-
auto *IPM = SRL->getOperand(0).getNode();
8705-
if (!IPM || IPM->getOpcode() != SystemZISD::IPM)
8706-
return false;
8707-
auto IPMOp0 = IPM->getOperand(0).getNode();
8708-
if (!IPMOp0 || IPMOp0->getNumOperands() < 2)
8709-
return false;
8710-
auto RN = dyn_cast<RegisterSDNode>(IPMOp0->getOperand(1));
8711-
if (!RN || !RN->getReg().isPhysical() || RN->getReg() != SystemZ::CC)
8698+
// Merging versus split in multiple branches cost.
8699+
TargetLoweringBase::CondMergingParams
8700+
SystemZTargetLowering::getJumpConditionMergingParams(Instruction::BinaryOps Opc,
8701+
const Value *Lhs,
8702+
const Value *Rhs) const {
8703+
const auto isFlagOutOpCC = [](const Value *V) {
8704+
using namespace llvm::PatternMatch;
8705+
const Value *RHSVal;
8706+
const APInt *RHSC;
8707+
if (const auto *I = dyn_cast<Instruction>(V)) {
8708+
if (match(I->getOperand(0), m_And(m_Value(RHSVal), m_APInt(RHSC))) ||
8709+
match(I, m_Cmp(m_Value(RHSVal), m_APInt(RHSC)))) {
8710+
if (const auto *CB = dyn_cast<CallBase>(RHSVal)) {
8711+
if (CB->isInlineAsm()) {
8712+
const InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
8713+
return IA &&
8714+
IA->getConstraintString().find("{@cc}") != std::string::npos;
8715+
}
8716+
}
8717+
}
8718+
}
87128719
return false;
8713-
return true;
8720+
};
8721+
// Pattern (ICmp %asm) or (ICmp (And %asm)).
8722+
// Cost of longest dependency chain (ICmp, And) is 2. CostThreshold or
8723+
// BaseCost can be set >=2. If cost of instruction <= CostThreshold
8724+
// conditionals will be merged or else conditionals will be split.
8725+
if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8726+
return {3, 0, -1};
8727+
// Default.
8728+
return {-1, -1, -1};
87148729
}
87158730

87168731
SDValue SystemZTargetLowering::combineBR_CCMASK(

0 commit comments

Comments
 (0)