[clang] [llvm] [CT] Updated CT X86 test for the LLVM 21 changes (PR #164045)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 17 20:02:23 PDT 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp,h,c -- clang/test/Sema/builtin-ct-select-edge-cases.c clang/test/Sema/builtin-ct-select.c clang/lib/Basic/Targets/AArch64.cpp clang/lib/Basic/Targets/ARM.cpp clang/lib/Basic/Targets/X86.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Sema/SemaChecking.cpp llvm/include/llvm/CodeGen/ISDOpcodes.h llvm/include/llvm/CodeGen/SelectionDAG.h llvm/include/llvm/CodeGen/SelectionDAGNodes.h llvm/include/llvm/CodeGen/TargetLowering.h llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.h llvm/lib/Target/AArch64/AArch64InstrInfo.cpp llvm/lib/Target/AArch64/AArch64MCInstLower.cpp llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/lib/Target/ARM/ARMBaseInstrInfo.h llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/ARMISelLowering.h llvm/lib/Target/ARM/ARMTargetMachine.cpp llvm/lib/Target/X86/X86ISelLowering.cpp llvm/lib/Target/X86/X86ISelLowering.h llvm/lib/Target/X86/X86InstrInfo.cpp llvm/lib/Target/X86/X86InstrInfo.h llvm/lib/Target/X86/X86TargetMachine.cpp --diff_from_common_commit
``````````
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 25b95ce02..c84184e88 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -25,8 +25,8 @@
#include "PatternInit.h"
#include "TargetInfo.h"
#include "clang/AST/OSLog.h"
-#include "clang/AST/StmtVisitor.h"
#include "clang/AST/OperationKinds.h"
+#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/TargetBuiltins.h"
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index d7c283367..3e23458f9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3477,11 +3477,13 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (TheCall->getNumArgs() != 3) {
// Simple argument count check without complex diagnostics
if (TheCall->getNumArgs() < 3) {
- return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
+ return Diag(TheCall->getEndLoc(),
+ diag::err_typecheck_call_too_few_args_at_least)
<< 0 << 3 << TheCall->getNumArgs() << 0
<< TheCall->getCallee()->getSourceRange();
} else {
- return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_many_args)
+ return Diag(TheCall->getEndLoc(),
+ diag::err_typecheck_call_too_many_args)
<< 0 << 3 << TheCall->getNumArgs() << 0
<< TheCall->getCallee()->getSourceRange();
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 54d51aaa1..98a830714 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -4146,23 +4146,29 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
EVT ScalarVT = VT.getScalarType();
for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
SDValue IdxVal = DAG.getConstant(Idx, dl, MVT::i64);
- SDValue TVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ScalarVT, Tmp2, IdxVal);
- SDValue FVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ScalarVT, Tmp3, IdxVal);
- Elements.push_back(DAG.getCTSelect(dl, ScalarVT, Tmp1, TVal, FVal, Node->getFlags()));
+ SDValue TVal =
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ScalarVT, Tmp2, IdxVal);
+ SDValue FVal =
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ScalarVT, Tmp3, IdxVal);
+ Elements.push_back(
+ DAG.getCTSelect(dl, ScalarVT, Tmp1, TVal, FVal, Node->getFlags()));
}
Tmp1 = DAG.getBuildVector(VT, dl, Elements);
} else if (VT.isFloatingPoint()) {
EVT IntegerVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
Tmp2 = DAG.getBitcast(IntegerVT, Tmp2);
Tmp3 = DAG.getBitcast(IntegerVT, Tmp3);
- Tmp1 = DAG.getBitcast(VT, DAG.getCTSelect(dl, IntegerVT, Tmp1, Tmp2, Tmp3, Node->getFlags()));
+ Tmp1 = DAG.getBitcast(VT, DAG.getCTSelect(dl, IntegerVT, Tmp1, Tmp2, Tmp3,
+ Node->getFlags()));
} else {
assert(VT.isInteger());
EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
auto [Tmp2Lo, Tmp2Hi] = DAG.SplitScalar(Tmp2, dl, HalfVT, HalfVT);
auto [Tmp3Lo, Tmp3Hi] = DAG.SplitScalar(Tmp3, dl, HalfVT, HalfVT);
- SDValue ResLo = DAG.getCTSelect(dl, HalfVT, Tmp1, Tmp2Lo, Tmp3Lo, Node->getFlags());
- SDValue ResHi = DAG.getCTSelect(dl, HalfVT, Tmp1, Tmp2Hi, Tmp3Hi, Node->getFlags());
+ SDValue ResLo =
+ DAG.getCTSelect(dl, HalfVT, Tmp1, Tmp2Lo, Tmp3Lo, Node->getFlags());
+ SDValue ResHi =
+ DAG.getCTSelect(dl, HalfVT, Tmp1, Tmp2Hi, Tmp3Hi, Node->getFlags());
Tmp1 = DAG.getNode(ISD::BUILD_PAIR, dl, VT, ResLo, ResHi);
Tmp1->setFlags(Node->getFlags());
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 90d9ac76b..7d92eba12 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6501,7 +6501,7 @@ SDValue SelectionDAGBuilder::createProtectedCtSelectFallbackChain(
EVT WorkingVT = VT;
SDValue Chain = DAG.getEntryNode();
- MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo();
+ MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo();
if (VT.isVector() && !Cond.getValueType().isVector()) {
ElementCount NumElems = VT.getVectorElementCount();
@@ -6554,7 +6554,7 @@ SDValue SelectionDAGBuilder::createProtectedCtSelectFallbackChain(
if (CanUseChaining) {
// Apply chaining through registers for additional protection
-
+
const TargetRegisterClass *RC = TLI.getRegClassFor(WorkingVT.getSimpleVT());
Register TMReg = MRI.createVirtualRegister(RC);
Chain = DAG.getCopyToReg(Chain, DL, TMReg, TM);
@@ -6569,10 +6569,9 @@ SDValue SelectionDAGBuilder::createProtectedCtSelectFallbackChain(
} else {
// For scalable vectors, check if the target has register class support
// This is target-specific - RISC-V might not support this directly
- CanUseChaining = false; // Conservative: disable for scalable vectors
+ CanUseChaining = false; // Conservative: disable for scalable vectors
}
-
SDValue Result = DAG.getNode(ISD::OR, DL, WorkingVT, TM, FM);
// Convert back if needed
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 89e949d96..e9bc85b52 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -511,7 +511,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::BR_CC, MVT::f64, Custom);
setOperationAction(ISD::SELECT, MVT::i32, Custom);
setOperationAction(ISD::SELECT, MVT::i64, Custom);
- setOperationAction(ISD::CTSELECT, MVT::i8, Promote);
+ setOperationAction(ISD::CTSELECT, MVT::i8, Promote);
setOperationAction(ISD::CTSELECT, MVT::i16, Promote);
setOperationAction(ISD::CTSELECT, MVT::i32, Custom);
setOperationAction(ISD::CTSELECT, MVT::i64, Custom);
@@ -534,7 +534,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
MVT elemType = VT.getVectorElementType();
if (elemType == MVT::i8 || elemType == MVT::i16) {
setOperationAction(ISD::CTSELECT, VT, Promote);
- } else if ((elemType == MVT::f16 || elemType == MVT::bf16) && !Subtarget->hasFullFP16()) {
+ } else if ((elemType == MVT::f16 || elemType == MVT::bf16) &&
+ !Subtarget->hasFullFP16()) {
setOperationAction(ISD::CTSELECT, VT, Promote);
} else {
setOperationAction(ISD::CTSELECT, VT, Expand);
@@ -3351,7 +3352,9 @@ void AArch64TargetLowering::fixupPtrauthDiscriminator(
IntDiscOp.setImm(IntDisc);
}
-MachineBasicBlock *AArch64TargetLowering::EmitCTSELECT(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode) const {
+MachineBasicBlock *AArch64TargetLowering::EmitCTSELECT(MachineInstr &MI,
+ MachineBasicBlock *MBB,
+ unsigned Opcode) const {
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
DebugLoc DL = MI.getDebugLoc();
MachineInstrBuilder Builder = BuildMI(*MBB, MI, DL, TII->get(Opcode));
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 415360ea5..73daf0266 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -207,7 +207,8 @@ public:
MachineOperand &AddrDiscOp,
const TargetRegisterClass *AddrDiscRC) const;
- MachineBasicBlock *EmitCTSELECT(MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode) const;
+ MachineBasicBlock *EmitCTSELECT(MachineInstr &MI, MachineBasicBlock *BB,
+ unsigned Opcode) const;
MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
@@ -929,9 +930,7 @@ private:
return VT.isScalableVector();
}
- bool isSelectSupported(SelectSupportKind Kind) const override {
- return true;
- }
+ bool isSelectSupported(SelectSupportKind Kind) const override { return true; }
};
namespace AArch64 {
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 7b3fbc64a..f5c1d0d2e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2113,7 +2113,8 @@ bool AArch64InstrInfo::removeCmpToZeroOrOne(
return true;
}
-static inline void expandCtSelect(MachineBasicBlock &MBB, MachineInstr &MI, DebugLoc &DL, const MCInstrDesc &MCID) {
+static inline void expandCtSelect(MachineBasicBlock &MBB, MachineInstr &MI,
+ DebugLoc &DL, const MCInstrDesc &MCID) {
MachineInstrBuilder Builder = BuildMI(MBB, MI, DL, MCID);
for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
Builder.add(MI.getOperand(Idx));
@@ -2129,24 +2130,24 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
DebugLoc DL = MI.getDebugLoc();
switch (MI.getOpcode()) {
- case AArch64::I32CTSELECT:
- expandCtSelect(MBB, MI, DL, get(AArch64::CSELWr));
- return true;
- case AArch64::I64CTSELECT:
- expandCtSelect(MBB, MI, DL, get(AArch64::CSELXr));
- return true;
- case AArch64::BF16CTSELECT:
- expandCtSelect(MBB, MI, DL, get(AArch64::FCSELHrrr));
- return true;
- case AArch64::F16CTSELECT:
- expandCtSelect(MBB, MI, DL, get(AArch64::FCSELHrrr));
- return true;
- case AArch64::F32CTSELECT:
- expandCtSelect(MBB, MI, DL, get(AArch64::FCSELSrrr));
- return true;
- case AArch64::F64CTSELECT:
- expandCtSelect(MBB, MI, DL, get(AArch64::FCSELDrrr));
- return true;
+ case AArch64::I32CTSELECT:
+ expandCtSelect(MBB, MI, DL, get(AArch64::CSELWr));
+ return true;
+ case AArch64::I64CTSELECT:
+ expandCtSelect(MBB, MI, DL, get(AArch64::CSELXr));
+ return true;
+ case AArch64::BF16CTSELECT:
+ expandCtSelect(MBB, MI, DL, get(AArch64::FCSELHrrr));
+ return true;
+ case AArch64::F16CTSELECT:
+ expandCtSelect(MBB, MI, DL, get(AArch64::FCSELHrrr));
+ return true;
+ case AArch64::F32CTSELECT:
+ expandCtSelect(MBB, MI, DL, get(AArch64::FCSELSrrr));
+ return true;
+ case AArch64::F64CTSELECT:
+ expandCtSelect(MBB, MI, DL, get(AArch64::FCSELDrrr));
+ return true;
}
if (MI.getOpcode() != TargetOpcode::LOAD_STACK_GUARD &&
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index fa10c0052..b9d0a3bac 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1552,8 +1552,9 @@ bool ARMBaseInstrInfo::expandCtSelectVector(MachineInstr &MI) const {
unsigned RsbOp = Subtarget.isThumb2() ? ARM::t2RSBri : ARM::RSBri;
- // Any vector pseudo has: ((outs $dst, $tmp_mask, $bcast_mask), (ins $src1, $src2, $cond))
- Register VectorMaskReg = MI.getOperand(2).getReg();
+ // Any vector pseudo has: ((outs $dst, $tmp_mask, $bcast_mask), (ins $src1,
+ // $src2, $cond))
+ Register VectorMaskReg = MI.getOperand(2).getReg();
Register Src1Reg = MI.getOperand(3).getReg();
Register Src2Reg = MI.getOperand(4).getReg();
Register CondReg = MI.getOperand(5).getReg();
@@ -1564,47 +1565,46 @@ bool ARMBaseInstrInfo::expandCtSelectVector(MachineInstr &MI) const {
// When cond = 0: mask = 0x00000000.
// When cond = 1: mask = 0xFFFFFFFF.
- MachineInstr *FirstNewMI =
- BuildMI(*MBB, MI, DL, get(RsbOp), MaskReg)
- .addReg(CondReg)
- .addImm(0)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp())
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
-
+ MachineInstr *FirstNewMI = BuildMI(*MBB, MI, DL, get(RsbOp), MaskReg)
+ .addReg(CondReg)
+ .addImm(0)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp())
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
+
// 2. A = src1 & mask
// For vectors, broadcast the scalar mask so it matches operand size.
BuildMI(*MBB, MI, DL, get(BroadcastOp), VectorMaskReg)
- .addReg(MaskReg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(MaskReg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
BuildMI(*MBB, MI, DL, get(AndOp), DestReg)
- .addReg(Src1Reg)
- .addReg(VectorMaskReg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(Src1Reg)
+ .addReg(VectorMaskReg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 3. B = src2 & ~mask
BuildMI(*MBB, MI, DL, get(BicOp), VectorMaskReg)
- .addReg(Src2Reg)
- .addReg(VectorMaskReg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(Src2Reg)
+ .addReg(VectorMaskReg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 4. result = A | B
auto LastNewMI = BuildMI(*MBB, MI, DL, get(OrrOp), DestReg)
- .addReg(DestReg)
- .addReg(VectorMaskReg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(DestReg)
+ .addReg(VectorMaskReg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
auto BundleStart = FirstNewMI->getIterator();
auto BundleEnd = LastNewMI->getIterator();
// Add instruction bundling
finalizeBundle(*MBB, BundleStart, std::next(BundleEnd));
-
+
MI.eraseFromParent();
return true;
}
@@ -1614,8 +1614,8 @@ bool ARMBaseInstrInfo::expandCtSelectThumb(MachineInstr &MI) const {
MachineBasicBlock *MBB = MI.getParent();
DebugLoc DL = MI.getDebugLoc();
- // pseudos in thumb1 mode have: (outs $dst, $tmp_mask), (ins $src1, $src2, $cond))
- // register class here is always tGPR.
+ // pseudos in thumb1 mode have: (outs $dst, $tmp_mask), (ins $src1, $src2,
+ // $cond)) register class here is always tGPR.
Register DestReg = MI.getOperand(0).getReg();
Register MaskReg = MI.getOperand(1).getReg();
Register Src1Reg = MI.getOperand(2).getReg();
@@ -1631,50 +1631,50 @@ bool ARMBaseInstrInfo::expandCtSelectThumb(MachineInstr &MI) const {
unsigned ShiftAmount = RegSize - 1;
// Option 1: Shift-based mask (preferred - no flag modification)
- MachineInstr *FirstNewMI =
- BuildMI(*MBB, MI, DL, get(ARM::tMOVr), MaskReg)
- .addReg(CondReg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ MachineInstr *FirstNewMI = BuildMI(*MBB, MI, DL, get(ARM::tMOVr), MaskReg)
+ .addReg(CondReg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
- // Instead of using RSB, we can use LSL and ASR to get the mask. This is to avoid the flag modification caused by RSB.
+ // Instead of using RSB, we can use LSL and ASR to get the mask. This is to
+ // avoid the flag modification caused by RSB.
BuildMI(*MBB, MI, DL, get(ARM::tLSLri), MaskReg)
- .addReg(MaskReg)
- .addImm(ShiftAmount)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(MaskReg)
+ .addImm(ShiftAmount)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
BuildMI(*MBB, MI, DL, get(ARM::tASRri), MaskReg)
- .addReg(MaskReg)
- .addImm(ShiftAmount)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(MaskReg)
+ .addImm(ShiftAmount)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 2. xor_diff = src1 ^ src2
BuildMI(*MBB, MI, DL, get(ARM::tMOVr), DestReg)
- .addReg(Src1Reg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(Src1Reg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
BuildMI(*MBB, MI, DL, get(ARM::tEOR), DestReg)
- .addReg(DestReg)
- .addReg(Src2Reg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(DestReg)
+ .addReg(Src2Reg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 3. masked_xor = xor_diff & mask
BuildMI(*MBB, MI, DL, get(ARM::tAND), DestReg)
- .addReg(DestReg)
- .addReg(MaskReg, RegState::Kill)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(DestReg)
+ .addReg(MaskReg, RegState::Kill)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 4. result = src2 ^ masked_xor
auto LastMI = BuildMI(*MBB, MI, DL, get(ARM::tEOR), DestReg)
- .addReg(DestReg)
- .addReg(Src2Reg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(DestReg)
+ .addReg(Src2Reg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// Add instruction bundling
auto BundleStart = FirstNewMI->getIterator();
@@ -1708,39 +1708,42 @@ bool ARMBaseInstrInfo::expandCtSelect(MachineInstr &MI) const {
}
unsigned Opcode = MI.getOpcode();
- bool IsFloat = Opcode == ARM::CTSELECTf32 || Opcode == ARM::CTSELECTf16 || Opcode == ARM::CTSELECTbf16;
+ bool IsFloat = Opcode == ARM::CTSELECTf32 || Opcode == ARM::CTSELECTf16 ||
+ Opcode == ARM::CTSELECTbf16;
MachineInstr *FirstNewMI = nullptr;
if (IsFloat) {
- // Each float pseudo has: (outs $dst, $tmp_mask, $scratch1, $scratch2), (ins $src1, $src2, $cond))
- // We use two scratch registers in tablegen for bitwise ops on float types,.
- Register GPRScratch1 = MI.getOperand(2).getReg();
- Register GPRScratch2 = MI.getOperand(3).getReg();
-
- // choice a from __builtin_ct_select(cond, a, b)
- Src1Reg = MI.getOperand(4).getReg();
- // choice b from __builtin_ct_select(cond, a, b)
- Src2Reg = MI.getOperand(5).getReg();
- // cond from __builtin_ct_select(cond, a, b)
- CondReg = MI.getOperand(6).getReg();
+ // Each float pseudo has: (outs $dst, $tmp_mask, $scratch1, $scratch2), (ins
+ // $src1, $src2, $cond)) We use two scratch registers in tablegen for
+ // bitwise ops on float types,.
+ Register GPRScratch1 = MI.getOperand(2).getReg();
+ Register GPRScratch2 = MI.getOperand(3).getReg();
+
+ // choice a from __builtin_ct_select(cond, a, b)
+ Src1Reg = MI.getOperand(4).getReg();
+ // choice b from __builtin_ct_select(cond, a, b)
+ Src2Reg = MI.getOperand(5).getReg();
+ // cond from __builtin_ct_select(cond, a, b)
+ CondReg = MI.getOperand(6).getReg();
// Move fp src1 to GPR scratch1 so we can do our bitwise ops
FirstNewMI = BuildMI(*MBB, MI, DL, get(ARM::VMOVRS), GPRScratch1)
- .addReg(Src1Reg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
-
+ .addReg(Src1Reg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
+
// Move src2 to scratch2
BuildMI(*MBB, MI, DL, get(ARM::VMOVRS), GPRScratch2)
- .addReg(Src2Reg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
-
+ .addReg(Src2Reg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
+
Src1Reg = GPRScratch1;
Src2Reg = GPRScratch2;
// Reuse GPRScratch1 for dest after we are done working with src1.
DestReg = GPRScratch1;
} else {
- // Any non-float, non-vector pseudo has: (outs $dst, $tmp_mask), (ins $src1, $src2, $cond))
+ // Any non-float, non-vector pseudo has: (outs $dst, $tmp_mask), (ins $src1,
+ // $src2, $cond))
Src1Reg = MI.getOperand(2).getReg();
Src2Reg = MI.getOperand(3).getReg();
CondReg = MI.getOperand(4).getReg();
@@ -1752,11 +1755,11 @@ bool ARMBaseInstrInfo::expandCtSelect(MachineInstr &MI) const {
// When cond = 0: mask = 0x00000000.
// When cond = 1: mask = 0xFFFFFFFF.
auto TmpNewMI = BuildMI(*MBB, MI, DL, get(RsbOp), MaskReg)
- .addReg(CondReg)
- .addImm(0)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp())
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(CondReg)
+ .addImm(0)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp())
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// We use the first instruction in the bundle as the first instruction.
if (!FirstNewMI)
@@ -1764,34 +1767,34 @@ bool ARMBaseInstrInfo::expandCtSelect(MachineInstr &MI) const {
// 2. A = src1 & mask
BuildMI(*MBB, MI, DL, get(AndOp), DestReg)
- .addReg(Src1Reg)
- .addReg(MaskReg)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp())
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(Src1Reg)
+ .addReg(MaskReg)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp())
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 3. B = src2 & ~mask
BuildMI(*MBB, MI, DL, get(BicOp), MaskReg)
- .addReg(Src2Reg)
- .addReg(MaskReg)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp())
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(Src2Reg)
+ .addReg(MaskReg)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp())
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// 4. result = A | B
auto LastNewMI = BuildMI(*MBB, MI, DL, get(OrrOp), DestReg)
- .addReg(DestReg)
- .addReg(MaskReg)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp())
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(DestReg)
+ .addReg(MaskReg)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp())
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
if (IsFloat) {
// Return our result from GPR to the correct register type.
- LastNewMI =BuildMI(*MBB, MI, DL, get(ARM::VMOVSR), DestRegSavedRef)
- .addReg(DestReg)
- .add(predOps(ARMCC::AL))
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ LastNewMI = BuildMI(*MBB, MI, DL, get(ARM::VMOVSR), DestRegSavedRef)
+ .addReg(DestReg)
+ .add(predOps(ARMCC::AL))
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
}
auto BundleStart = FirstNewMI->getIterator();
@@ -1799,7 +1802,7 @@ bool ARMBaseInstrInfo::expandCtSelect(MachineInstr &MI) const {
// Add instruction bundling
finalizeBundle(*MBB, BundleStart, std::next(BundleEnd));
-
+
MI.eraseFromParent();
return true;
}
@@ -1820,39 +1823,33 @@ bool ARMBaseInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
if (opcode == ARM::CTSELECTf64) {
if (Subtarget.isThumb1Only()) {
- LLVM_DEBUG(dbgs() << "Opcode (thumb1 subtarget) " << opcode << "replaced by: " << MI);
+ LLVM_DEBUG(dbgs() << "Opcode (thumb1 subtarget) " << opcode
+ << "replaced by: " << MI);
return expandCtSelectThumb(MI);
} else {
- LLVM_DEBUG(dbgs() << "Opcode (vector) " << opcode << "replaced by: " << MI);
+ LLVM_DEBUG(dbgs() << "Opcode (vector) " << opcode
+ << "replaced by: " << MI);
return expandCtSelectVector(MI);
}
}
- if (opcode == ARM::CTSELECTv8i8 ||
- opcode == ARM::CTSELECTv4i16 ||
- opcode == ARM::CTSELECTv2i32 ||
- opcode == ARM::CTSELECTv1i64 ||
- opcode == ARM::CTSELECTv2f32 ||
- opcode == ARM::CTSELECTv4f16 ||
- opcode == ARM::CTSELECTv4bf16 ||
- opcode == ARM::CTSELECTv16i8 ||
- opcode == ARM::CTSELECTv8i16 ||
- opcode == ARM::CTSELECTv4i32 ||
- opcode == ARM::CTSELECTv2i64 ||
- opcode == ARM::CTSELECTv4f32 ||
- opcode == ARM::CTSELECTv2f64 ||
- opcode == ARM::CTSELECTv8f16 ||
+ if (opcode == ARM::CTSELECTv8i8 || opcode == ARM::CTSELECTv4i16 ||
+ opcode == ARM::CTSELECTv2i32 || opcode == ARM::CTSELECTv1i64 ||
+ opcode == ARM::CTSELECTv2f32 || opcode == ARM::CTSELECTv4f16 ||
+ opcode == ARM::CTSELECTv4bf16 || opcode == ARM::CTSELECTv16i8 ||
+ opcode == ARM::CTSELECTv8i16 || opcode == ARM::CTSELECTv4i32 ||
+ opcode == ARM::CTSELECTv2i64 || opcode == ARM::CTSELECTv4f32 ||
+ opcode == ARM::CTSELECTv2f64 || opcode == ARM::CTSELECTv8f16 ||
opcode == ARM::CTSELECTv8bf16) {
LLVM_DEBUG(dbgs() << "Opcode (vector) " << opcode << "replaced by: " << MI);
return expandCtSelectVector(MI);
}
- if (opcode == ARM::CTSELECTint ||
- opcode == ARM::CTSELECTf16 ||
- opcode == ARM::CTSELECTbf16 ||
- opcode == ARM::CTSELECTf32) {
+ if (opcode == ARM::CTSELECTint || opcode == ARM::CTSELECTf16 ||
+ opcode == ARM::CTSELECTbf16 || opcode == ARM::CTSELECTf32) {
if (Subtarget.isThumb1Only()) {
- LLVM_DEBUG(dbgs() << "Opcode (thumb1 subtarget) " << opcode << "replaced by: " << MI);
+ LLVM_DEBUG(dbgs() << "Opcode (thumb1 subtarget) " << opcode
+ << "replaced by: " << MI);
return expandCtSelectThumb(MI);
} else {
LLVM_DEBUG(dbgs() << "Opcode " << opcode << "replaced by: " << MI);
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 62f5b21a7..3fdc5734b 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -4203,7 +4203,7 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
case ARMISD::CTSELECT: {
EVT VT = N->getValueType(0);
unsigned PseudoOpcode;
- bool IsFloat = false;
+ bool IsFloat = false;
bool IsVector = false;
if (VT == MVT::f16) {
@@ -4269,18 +4269,18 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
SmallVector<EVT, 4> VTs;
- VTs.push_back(VT); // $dst
- VTs.push_back(MVT::i32); // $tmp_mask (always GPR)
-
+ VTs.push_back(VT); // $dst
+ VTs.push_back(MVT::i32); // $tmp_mask (always GPR)
+
if (IsVector) {
- VTs.push_back(VT); // $bcast_mask (same type as dst for vectors)
+ VTs.push_back(VT); // $bcast_mask (same type as dst for vectors)
} else if (IsFloat) {
- VTs.push_back(MVT::i32); // $scratch1 (GPR)
- VTs.push_back(MVT::i32); // $scratch2 (GPR)
+ VTs.push_back(MVT::i32); // $scratch1 (GPR)
+ VTs.push_back(MVT::i32); // $scratch2 (GPR)
}
-
+
// src1, src2, cond
- SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) };
+ SDValue Ops[] = {N->getOperand(0), N->getOperand(1), N->getOperand(2)};
SDNode *ResNode = CurDAG->getMachineNode(PseudoOpcode, SDLoc(N), VTs, Ops);
ReplaceNode(N, ResNode);
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index addd612f0..5481d7e2d 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -203,7 +203,7 @@ void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
setOperationAction(ISD::SELECT, VT, Expand);
setOperationAction(ISD::SELECT_CC, VT, Expand);
setOperationAction(ISD::VSELECT, VT, Expand);
- setOperationAction(ISD::CTSELECT, VT, Custom);
+ setOperationAction(ISD::CTSELECT, VT, Custom);
setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
if (VT.isInteger()) {
setOperationAction(ISD::SHL, VT, Custom);
@@ -422,12 +422,12 @@ void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
}
// small exotic vectors get scalarised for ctselect
- setOperationAction(ISD::CTSELECT, MVT::v1i8, Expand);
+ setOperationAction(ISD::CTSELECT, MVT::v1i8, Expand);
setOperationAction(ISD::CTSELECT, MVT::v1i16, Expand);
setOperationAction(ISD::CTSELECT, MVT::v1i32, Expand);
setOperationAction(ISD::CTSELECT, MVT::v1f32, Expand);
- setOperationAction(ISD::CTSELECT, MVT::v2i8, Expand);
-
+ setOperationAction(ISD::CTSELECT, MVT::v2i8, Expand);
+
setOperationAction(ISD::CTSELECT, MVT::v2i16, Promote);
setOperationPromotedToType(ISD::CTSELECT, MVT::v2i16, MVT::v4i16);
setOperationAction(ISD::CTSELECT, MVT::v4i8, Promote);
@@ -1264,15 +1264,15 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
- setOperationAction(ISD::CTSELECT, MVT::i8, Promote);
- setOperationAction(ISD::CTSELECT, MVT::i16, Promote);
+ setOperationAction(ISD::CTSELECT, MVT::i8, Promote);
+ setOperationAction(ISD::CTSELECT, MVT::i16, Promote);
setOperationPromotedToType(ISD::CTSELECT, MVT::i16, MVT::i32);
- setOperationAction(ISD::CTSELECT, MVT::i32, Custom);
- setOperationAction(ISD::CTSELECT, MVT::i64, Expand);
- setOperationAction(ISD::CTSELECT, MVT::f32, Custom);
- setOperationAction(ISD::CTSELECT, MVT::f64, Custom);
-
+ setOperationAction(ISD::CTSELECT, MVT::i32, Custom);
+ setOperationAction(ISD::CTSELECT, MVT::i64, Expand);
+ setOperationAction(ISD::CTSELECT, MVT::f32, Custom);
+ setOperationAction(ISD::CTSELECT, MVT::f64, Custom);
+
// Handle f16 and bf16 without falling back to select from ctselect.
setTargetDAGCombine({ISD::CTSELECT});
@@ -1280,7 +1280,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
setOperationAction(ISD::SETCC, MVT::f16, Expand);
setOperationAction(ISD::SELECT, MVT::f16, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f16, Custom);
- setOperationAction(ISD::CTSELECT, MVT::f16, Custom);
+ setOperationAction(ISD::CTSELECT, MVT::f16, Custom);
}
if (Subtarget->hasBF16()) {
@@ -10658,7 +10658,8 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::SELECT: return LowerSELECT(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
- case ISD::CTSELECT: return LowerCTSELECT(Op, DAG);
+ case ISD::CTSELECT:
+ return LowerCTSELECT(Op, DAG);
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
case ISD::BR_CC: return LowerBR_CC(Op, DAG);
case ISD::BR_JT: return LowerBR_JT(Op, DAG);
@@ -10876,35 +10877,35 @@ void ARMTargetLowering::ReplaceNodeResults(SDNode *N,
Res = LowerFP_TO_INT_SAT(SDValue(N, 0), DAG, Subtarget);
break;
case ISD::CTSELECT: {
- EVT VT = N->getValueType(0);
-
- // Handle f16/bf16 type promotion while preserving ctselect
- if (VT == MVT::f16 || VT == MVT::bf16) {
- SDLoc DL(N);
- SDValue Cond = N->getOperand(0);
- SDValue TrueVal = N->getOperand(1);
- SDValue FalseVal = N->getOperand(2);
-
- // Bitcast to i16, then promote to i32
- SDValue TrueInt = DAG.getBitcast(MVT::i16, TrueVal);
- SDValue FalseInt = DAG.getBitcast(MVT::i16, FalseVal);
-
- TrueInt = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, TrueInt);
- FalseInt = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, FalseInt);
-
- // Normalize condition
- SDValue One = DAG.getConstant(1, DL, MVT::i32);
- SDValue CondNorm = DAG.getNode(ISD::AND, DL, MVT::i32, Cond, One);
-
- // Create i32 ctselect that will go through normal lowering
- Res = DAG.getNode(ISD::CTSELECT, DL, MVT::i32,
- CondNorm, TrueInt, FalseInt);
- } else {
- // For other types, use existing lowering
- Res = LowerCTSELECT(SDValue(N, 0), DAG);
- }
- break;
+ EVT VT = N->getValueType(0);
+
+ // Handle f16/bf16 type promotion while preserving ctselect
+ if (VT == MVT::f16 || VT == MVT::bf16) {
+ SDLoc DL(N);
+ SDValue Cond = N->getOperand(0);
+ SDValue TrueVal = N->getOperand(1);
+ SDValue FalseVal = N->getOperand(2);
+
+ // Bitcast to i16, then promote to i32
+ SDValue TrueInt = DAG.getBitcast(MVT::i16, TrueVal);
+ SDValue FalseInt = DAG.getBitcast(MVT::i16, FalseVal);
+
+ TrueInt = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, TrueInt);
+ FalseInt = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, FalseInt);
+
+ // Normalize condition
+ SDValue One = DAG.getConstant(1, DL, MVT::i32);
+ SDValue CondNorm = DAG.getNode(ISD::AND, DL, MVT::i32, Cond, One);
+
+ // Create i32 ctselect that will go through normal lowering
+ Res =
+ DAG.getNode(ISD::CTSELECT, DL, MVT::i32, CondNorm, TrueInt, FalseInt);
+ } else {
+ // For other types, use existing lowering
+ Res = LowerCTSELECT(SDValue(N, 0), DAG);
}
+ break;
+ }
}
if (Res.getNode())
Results.push_back(Res);
@@ -13461,28 +13462,29 @@ static SDValue PerformVQDMULHCombine(SDNode *N, SelectionDAG &DAG) {
DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts));
}
-static SDValue PerformCTSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
- const ARMSubtarget *Subtarget) {
+static SDValue PerformCTSELECTCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const ARMSubtarget *Subtarget) {
if (!DCI.isBeforeLegalize()) {
- return SDValue();
+ return SDValue();
}
-
+
SelectionDAG &DAG = DCI.DAG;
SDLoc DL(N);
-
+
EVT VT = N->getValueType(0);
if (VT == MVT::f16 || VT == MVT::bf16) {
SDValue Cond = N->getOperand(0);
SDValue TrueVal = N->getOperand(1);
SDValue FalseVal = N->getOperand(2);
-
+
SDValue TrueInt = DAG.getBitcast(MVT::i16, TrueVal);
SDValue FalseInt = DAG.getBitcast(MVT::i16, FalseVal);
-
+
// Create i16 ctselect - this will be promoted to i32 ctselect naturally
- SDValue Result = DAG.getNode(ISD::CTSELECT, DL, MVT::i16,
- Cond, TrueInt, FalseInt);
-
+ SDValue Result =
+ DAG.getNode(ISD::CTSELECT, DL, MVT::i16, Cond, TrueInt, FalseInt);
+
return DAG.getBitcast(VT, Result);
} else if (VT.isVector()) {
EVT EltVT = VT.getVectorElementType();
@@ -13490,7 +13492,7 @@ static SDValue PerformCTSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo
SDValue Cond = N->getOperand(0);
SDValue TrueVal = N->getOperand(1);
SDValue FalseVal = N->getOperand(2);
-
+
EVT IntVT;
switch (VT.getSimpleVT().SimpleTy) {
case MVT::v4f16:
@@ -13504,13 +13506,13 @@ static SDValue PerformCTSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo
default:
return SDValue(); // Unsupported vector type
}
-
+
SDValue TrueInt = DAG.getBitcast(IntVT, TrueVal);
SDValue FalseInt = DAG.getBitcast(IntVT, FalseVal);
-
- SDValue Result = DAG.getNode(ISD::CTSELECT, DL, IntVT,
- Cond, TrueInt, FalseInt);
-
+
+ SDValue Result =
+ DAG.getNode(ISD::CTSELECT, DL, IntVT, Cond, TrueInt, FalseInt);
+
return DAG.getBitcast(VT, Result);
}
}
@@ -19021,7 +19023,8 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
case ISD::SELECT_CC:
case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
- case ISD::CTSELECT: return PerformCTSELECTCombine(N, DCI, Subtarget);
+ case ISD::CTSELECT:
+ return PerformCTSELECTCombine(N, DCI, Subtarget);
case ISD::SETCC: return PerformVSetCCToVCTPCombine(N, DCI, Subtarget);
case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget);
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index 18d47d9c6..44981cc4e 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -520,7 +520,7 @@ void ARMPassConfig::addPreEmitPass() {
// Constant island pass work on unbundled instructions.
addPass(createUnpackMachineBundles([](const MachineFunction &MF) {
return MF.getSubtarget<ARMSubtarget>().isThumb2() ||
- MF.getFunction().hasFnAttribute("ct-select");
+ MF.getFunction().hasFnAttribute("ct-select");
}));
// Don't optimize barriers or block placement at -O0.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 570cdb627..de9d25489 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -29,9 +29,9 @@
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
-#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -25368,7 +25368,7 @@ static SDValue LowerSIGN_EXTEND_Mask(SDValue Op, const SDLoc &dl,
}
SDValue X86TargetLowering::LowerCTSELECT(SDValue Op, SelectionDAG &DAG) const {
- SDValue Cond = Op.getOperand(0); // condition
+ SDValue Cond = Op.getOperand(0); // condition
SDValue TrueOp = Op.getOperand(1); // true_value
SDValue FalseOp = Op.getOperand(2); // false_value
SDLoc DL(Op);
@@ -37964,10 +37964,8 @@ X86TargetLowering::emitPatchableEventCall(MachineInstr &MI,
/// This approach ensures that when i64 is type-legalized into two i32
/// operations, both operations share the same condition byte rather than
/// each independently reading (and destroying) EFLAGS.
-static MachineBasicBlock *
-emitCTSelectI386WithConditionMaterialization(MachineInstr &MI,
- MachineBasicBlock *BB,
- unsigned InternalPseudoOpcode) {
+static MachineBasicBlock *emitCTSelectI386WithConditionMaterialization(
+ MachineInstr &MI, MachineBasicBlock *BB, unsigned InternalPseudoOpcode) {
const TargetInstrInfo *TII = BB->getParent()->getSubtarget().getInstrInfo();
const MIMetadata MIMD(MI);
MachineFunction *MF = BB->getParent();
@@ -38011,12 +38009,12 @@ emitCTSelectI386WithConditionMaterialization(MachineInstr &MI,
}
BuildMI(*BB, MI, MIMD, TII->get(InternalPseudoOpcode))
- .addDef(DstReg) // dst (output)
- .addDef(TmpByteReg) // tmp_byte (output)
- .addDef(TmpMaskReg) // tmp_mask (output)
- .addReg(Src1Reg) // src1 (input)
- .addReg(Src2Reg) // src2 (input)
- .addReg(CondByteReg); // pre-materialized condition byte (input)
+ .addDef(DstReg) // dst (output)
+ .addDef(TmpByteReg) // tmp_byte (output)
+ .addDef(TmpMaskReg) // tmp_mask (output)
+ .addReg(Src1Reg) // src1 (input)
+ .addReg(Src2Reg) // src2 (input)
+ .addReg(CondByteReg); // pre-materialized condition byte (input)
MI.eraseFromParent();
return BB;
@@ -38042,8 +38040,8 @@ struct FPLoadMemOperands {
// Check if a virtual register is defined by a simple FP load instruction
// Returns the memory operands if it's a simple load, otherwise returns invalid
static FPLoadMemOperands getFPLoadMemOperands(Register Reg,
- MachineRegisterInfo &MRI,
- unsigned ExpectedLoadOpcode) {
+ MachineRegisterInfo &MRI,
+ unsigned ExpectedLoadOpcode) {
FPLoadMemOperands Result;
if (!Reg.isVirtual())
@@ -38062,9 +38060,9 @@ static FPLoadMemOperands getFPLoadMemOperands(Register Reg,
if (DefMI->hasOrderedMemoryRef())
return Result;
- // The load should have a single def (the destination register) and memory operands
- // Format: %reg = LD_Fpxxm <fi#N>, 1, %noreg, 0, %noreg
- // or: %reg = LD_Fpxxm %base, scale, %index, disp, %segment
+ // The load should have a single def (the destination register) and memory
+ // operands Format: %reg = LD_Fpxxm <fi#N>, 1, %noreg, 0, %noreg or: %reg =
+ // LD_Fpxxm %base, scale, %index, disp, %segment
if (DefMI->getNumOperands() < 6)
return Result;
@@ -38089,9 +38087,8 @@ static FPLoadMemOperands getFPLoadMemOperands(Register Reg,
// Check if this is a constant pool load
// Format: %reg = LD_Fpxxm $noreg, 1, $noreg, %const.N, $noreg
- if (BaseMO.isReg() && BaseMO.getReg() == X86::NoRegister &&
- ScaleMO.isImm() && IndexMO.isReg() &&
- IndexMO.getReg() == X86::NoRegister &&
+ if (BaseMO.isReg() && BaseMO.getReg() == X86::NoRegister && ScaleMO.isImm() &&
+ IndexMO.isReg() && IndexMO.getReg() == X86::NoRegister &&
DispMO.isCPI() && SegMO.isReg()) {
Result.IsValid = true;
Result.IsConstantPool = true;
@@ -38105,9 +38102,8 @@ static FPLoadMemOperands getFPLoadMemOperands(Register Reg,
// Check if this is a global variable load
// Format: %reg = LD_Fpxxm $noreg, 1, $noreg, @global_name, $noreg
- if (BaseMO.isReg() && BaseMO.getReg() == X86::NoRegister &&
- ScaleMO.isImm() && IndexMO.isReg() &&
- IndexMO.getReg() == X86::NoRegister &&
+ if (BaseMO.isReg() && BaseMO.getReg() == X86::NoRegister && ScaleMO.isImm() &&
+ IndexMO.isReg() && IndexMO.getReg() == X86::NoRegister &&
DispMO.isGlobal() && SegMO.isReg()) {
Result.IsValid = true;
Result.IsGlobal = true;
@@ -38121,8 +38117,8 @@ static FPLoadMemOperands getFPLoadMemOperands(Register Reg,
}
// Regular memory operands (e.g., pointer loads)
- if (BaseMO.isReg() && ScaleMO.isImm() && IndexMO.isReg() &&
- DispMO.isImm() && SegMO.isReg()) {
+ if (BaseMO.isReg() && ScaleMO.isImm() && IndexMO.isReg() && DispMO.isImm() &&
+ SegMO.isReg()) {
Result.IsValid = true;
Result.IsFrameIndex = false;
Result.IsConstantPool = false;
@@ -38148,7 +38144,8 @@ static MachineBasicBlock *emitCTSelectI386WithFpType(MachineInstr &MI,
unsigned RegSizeInByte = 4;
// Get operands
- // MI operands: %result:rfp80 = CTSELECT_I386 %false:rfp80, %true:rfp80, %cond:i8imm
+ // MI operands: %result:rfp80 = CTSELECT_I386 %false:rfp80, %true:rfp80,
+ // %cond:i8imm
unsigned DestReg = MI.getOperand(0).getReg();
unsigned FalseReg = MI.getOperand(1).getReg();
unsigned TrueReg = MI.getOperand(2).getReg();
@@ -38166,7 +38163,7 @@ static MachineBasicBlock *emitCTSelectI386WithFpType(MachineInstr &MI,
// Helper to load integer from memory operands
auto loadIntFromMemOperands = [&](const FPLoadMemOperands &MemOps,
- unsigned Offset) -> unsigned {
+ unsigned Offset) -> unsigned {
unsigned IntReg = MRI.createVirtualRegister(&X86::GR32RegClass);
MachineInstrBuilder MIB =
BuildMI(*BB, MI, MIMD, TII->get(X86::MOV32rm), IntReg);
@@ -38182,18 +38179,21 @@ static MachineBasicBlock *emitCTSelectI386WithFpType(MachineInstr &MI,
// Constant pool: base_reg + scale + index + CP_index + segment
// MOV32rm format: base, scale, index, displacement, segment
MIB.addReg(X86::NoRegister) // Base register
- .addImm(MemOps.ScaleVal) // Scale
- .addReg(MemOps.IndexReg) // Index register
- .addConstantPoolIndex(MemOps.ConstantPoolIndex, Offset) // Displacement (CP index)
- .addReg(MemOps.SegReg); // Segment
+ .addImm(MemOps.ScaleVal) // Scale
+ .addReg(MemOps.IndexReg) // Index register
+ .addConstantPoolIndex(MemOps.ConstantPoolIndex,
+ Offset) // Displacement (CP index)
+ .addReg(MemOps.SegReg); // Segment
} else if (MemOps.IsGlobal) {
// Global variable: base_reg + scale + index + global + segment
// MOV32rm format: base, scale, index, displacement, segment
MIB.addReg(X86::NoRegister) // Base register
- .addImm(MemOps.ScaleVal) // Scale
- .addReg(MemOps.IndexReg) // Index register
- .addGlobalAddress(MemOps.Global, MemOps.GlobalOffset + Offset) // Displacement (global address)
- .addReg(MemOps.SegReg); // Segment
+ .addImm(MemOps.ScaleVal) // Scale
+ .addReg(MemOps.IndexReg) // Index register
+ .addGlobalAddress(MemOps.Global,
+ MemOps.GlobalOffset +
+ Offset) // Displacement (global address)
+ .addReg(MemOps.SegReg); // Segment
} else {
// Regular memory: base_reg + scale + index + disp + segment
MIB.addReg(MemOps.BaseReg)
@@ -38208,45 +38208,47 @@ static MachineBasicBlock *emitCTSelectI386WithFpType(MachineInstr &MI,
// Optimized path: load integers directly from memory when both operands are
// memory loads, avoiding FP register round-trip
- auto emitCtSelectFromMemory = [&](unsigned NumValues,
- const FPLoadMemOperands &TrueMemOps,
- const FPLoadMemOperands &FalseMemOps,
- int ResultSlot) {
- for (unsigned Val = 0; Val < NumValues; ++Val) {
- unsigned Offset = Val * RegSizeInByte;
-
- // Load true and false values directly from their memory locations as integers
- unsigned TrueIntReg = loadIntFromMemOperands(TrueMemOps, Offset);
- unsigned FalseIntReg = loadIntFromMemOperands(FalseMemOps, Offset);
-
- // Use CTSELECT_I386_INT_GR32 pseudo instruction for constant-time selection
- unsigned ResultIntReg = MRI.createVirtualRegister(&X86::GR32RegClass);
- unsigned TmpByteReg = MRI.createVirtualRegister(&X86::GR8RegClass);
- unsigned TmpMaskReg = MRI.createVirtualRegister(&X86::GR32RegClass);
-
- BuildMI(*BB, MI, MIMD, TII->get(X86::CTSELECT_I386_INT_GR32rr))
- .addDef(ResultIntReg) // dst (output)
- .addDef(TmpByteReg) // tmp_byte (output)
- .addDef(TmpMaskReg) // tmp_mask (output)
- .addReg(FalseIntReg) // src1 (input) - false value
- .addReg(TrueIntReg) // src2 (input) - true value
- .addReg(CondByteReg); // pre-materialized condition byte (input)
-
- // Store result back to result slot
- BuildMI(*BB, MI, MIMD, TII->get(X86::MOV32mr))
- .addFrameIndex(ResultSlot)
- .addImm(1)
- .addReg(0)
- .addImm(Offset)
- .addReg(0)
- .addReg(ResultIntReg, RegState::Kill);
- }
- };
+ auto emitCtSelectFromMemory =
+ [&](unsigned NumValues, const FPLoadMemOperands &TrueMemOps,
+ const FPLoadMemOperands &FalseMemOps, int ResultSlot) {
+ for (unsigned Val = 0; Val < NumValues; ++Val) {
+ unsigned Offset = Val * RegSizeInByte;
+
+ // Load true and false values directly from their memory locations as
+ // integers
+ unsigned TrueIntReg = loadIntFromMemOperands(TrueMemOps, Offset);
+ unsigned FalseIntReg = loadIntFromMemOperands(FalseMemOps, Offset);
+
+ // Use CTSELECT_I386_INT_GR32 pseudo instruction for constant-time
+ // selection
+ unsigned ResultIntReg = MRI.createVirtualRegister(&X86::GR32RegClass);
+ unsigned TmpByteReg = MRI.createVirtualRegister(&X86::GR8RegClass);
+ unsigned TmpMaskReg = MRI.createVirtualRegister(&X86::GR32RegClass);
+
+ BuildMI(*BB, MI, MIMD, TII->get(X86::CTSELECT_I386_INT_GR32rr))
+ .addDef(ResultIntReg) // dst (output)
+ .addDef(TmpByteReg) // tmp_byte (output)
+ .addDef(TmpMaskReg) // tmp_mask (output)
+ .addReg(FalseIntReg) // src1 (input) - false value
+ .addReg(TrueIntReg) // src2 (input) - true value
+ .addReg(CondByteReg); // pre-materialized condition byte (input)
+
+ // Store result back to result slot
+ BuildMI(*BB, MI, MIMD, TII->get(X86::MOV32mr))
+ .addFrameIndex(ResultSlot)
+ .addImm(1)
+ .addReg(0)
+ .addImm(Offset)
+ .addReg(0)
+ .addReg(ResultIntReg, RegState::Kill);
+ }
+ };
- auto emitCtSelectWithPseudo = [&](unsigned NumValues, int TrueSlot, int FalseSlot, int ResultSlot) {
+ auto emitCtSelectWithPseudo = [&](unsigned NumValues, int TrueSlot,
+ int FalseSlot, int ResultSlot) {
for (unsigned Val = 0; Val < NumValues; ++Val) {
unsigned Offset = Val * RegSizeInByte;
-
+
// Load true and false values from stack as 32-bit integers
unsigned TrueIntReg = MRI.createVirtualRegister(&X86::GR32RegClass);
BuildMI(*BB, MI, MIMD, TII->get(X86::MOV32rm), TrueIntReg)
@@ -38264,18 +38266,19 @@ static MachineBasicBlock *emitCTSelectI386WithFpType(MachineInstr &MI,
.addImm(Offset)
.addReg(0);
- // Use CTSELECT_I386_INT_GR32 pseudo instruction for constant-time selection
+ // Use CTSELECT_I386_INT_GR32 pseudo instruction for constant-time
+ // selection
unsigned ResultIntReg = MRI.createVirtualRegister(&X86::GR32RegClass);
unsigned TmpByteReg = MRI.createVirtualRegister(&X86::GR8RegClass);
unsigned TmpMaskReg = MRI.createVirtualRegister(&X86::GR32RegClass);
-
+
BuildMI(*BB, MI, MIMD, TII->get(X86::CTSELECT_I386_INT_GR32rr))
- .addDef(ResultIntReg) // dst (output)
- .addDef(TmpByteReg) // tmp_byte (output)
- .addDef(TmpMaskReg) // tmp_mask (output)
- .addReg(FalseIntReg) // src1 (input) - false value
- .addReg(TrueIntReg) // src2 (input) - true value
- .addReg(CondByteReg); // pre-materialized condition byte (input)
+ .addDef(ResultIntReg) // dst (output)
+ .addDef(TmpByteReg) // tmp_byte (output)
+ .addDef(TmpMaskReg) // tmp_mask (output)
+ .addReg(FalseIntReg) // src1 (input) - false value
+ .addReg(TrueIntReg) // src2 (input) - true value
+ .addReg(CondByteReg); // pre-materialized condition byte (input)
// Store result back to result slot
BuildMI(*BB, MI, MIMD, TII->get(X86::MOV32mr))
@@ -38507,7 +38510,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return emitCTSelectI386WithFpType(MI, BB, X86::CTSELECT_I386_FP64rr);
case X86::CTSELECT_I386_FP80rr:
return emitCTSelectI386WithFpType(MI, BB, X86::CTSELECT_I386_FP80rr);
-
+
case X86::FP80_ADDr:
case X86::FP80_ADDm32: {
// Change the floating point control register to use double extended
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 9d979a14e..9893e351e 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -690,8 +690,7 @@ bool X86InstrInfo::expandCtSelectVector(MachineInstr &MI) const {
.addImm(31));
} else {
// Negate to convert 1 -> 0xFFFFFFFF, 0 -> 0x00000000 (negl %eax)
- recordInstr(BuildMI(*MBB, MI, DL, get(X86::NEG32r), TmpGPR)
- .addReg(TmpGPR));
+ recordInstr(BuildMI(*MBB, MI, DL, get(X86::NEG32r), TmpGPR).addReg(TmpGPR));
}
// Broadcast to TmpX (vector mask)
@@ -848,7 +847,8 @@ bool X86InstrInfo::expandCtSelectVector(MachineInstr &MI) const {
.setMIFlags(MachineInstr::MIFlag::NoMerge));
}
- assert(FirstInstr && LastInstr && "Expected at least one expanded instruction");
+ assert(FirstInstr && LastInstr &&
+ "Expected at least one expanded instruction");
auto BundleEnd = LastInstr->getIterator();
finalizeBundle(*MBB, FirstInstr->getIterator(), std::next(BundleEnd));
@@ -916,25 +916,28 @@ bool X86InstrInfo::expandCtSelectWithCMOV(MachineInstr &MI) const {
/// Expand i386-specific CTSELECT pseudo instructions (post-RA, constant-time)
/// These internal pseudos receive a pre-materialized condition byte from the
-/// custom inserter, avoiding EFLAGS corruption issues during i64 type legalization.
+/// custom inserter, avoiding EFLAGS corruption issues during i64 type
+/// legalization.
bool X86InstrInfo::expandCtSelectIntWithoutCMOV(MachineInstr &MI) const {
MachineBasicBlock *MBB = MI.getParent();
DebugLoc DL = MI.getDebugLoc();
// CTSELECT_I386_INT_GRxxrr has operands: (outs dst, tmp_byte, tmp_mask),
// (ins src1, src2, cond_byte)
- // Note: cond_byte is pre-materialized by custom inserter, not EFLAGS-dependent
+ // Note: cond_byte is pre-materialized by custom inserter, not
+ // EFLAGS-dependent
Register DstReg = MI.getOperand(0).getReg();
Register TmpByteReg = MI.getOperand(1).getReg();
Register TmpMaskReg = MI.getOperand(2).getReg();
Register Src1Reg = MI.getOperand(3).getReg();
Register Src2Reg = MI.getOperand(4).getReg();
- Register CondByteReg = MI.getOperand(5).getReg(); // Pre-materialized condition byte
+ Register CondByteReg =
+ MI.getOperand(5).getReg(); // Pre-materialized condition byte
// Determine instruction opcodes based on register width
unsigned MovZXOp, NegOp, MovOp, AndOp, NotOp, OrOp;
if (MI.getOpcode() == X86::CTSELECT_I386_INT_GR8rr) {
- MovZXOp = 0; // No zero-extend needed for GR8
+ MovZXOp = 0; // No zero-extend needed for GR8
NegOp = X86::NEG8r;
MovOp = X86::MOV8rr;
AndOp = X86::AND8rr;
@@ -963,8 +966,8 @@ bool X86InstrInfo::expandCtSelectIntWithoutCMOV(MachineInstr &MI) const {
// Step 1: Copy pre-materialized condition byte to TmpByteReg
// This allows the bundle to work with allocated temporaries
auto I1 = BuildMI(*MBB, MI, DL, get(X86::MOV8rr), TmpByteReg)
- .addReg(CondByteReg)
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(CondByteReg)
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
auto BundleStart = I1->getIterator();
// Step 2: Zero-extend condition byte to register width (0 or 1)
@@ -975,7 +978,9 @@ bool X86InstrInfo::expandCtSelectIntWithoutCMOV(MachineInstr &MI) const {
}
// Step 3: Convert condition to bitmask (NEG: 1 -> 0xFFFF..., 0 -> 0x0000...)
- Register MaskReg = (MI.getOpcode() == X86::CTSELECT_I386_INT_GR8rr) ? TmpByteReg : TmpMaskReg;
+ Register MaskReg = (MI.getOpcode() == X86::CTSELECT_I386_INT_GR8rr)
+ ? TmpByteReg
+ : TmpMaskReg;
BuildMI(*MBB, MI, DL, get(NegOp), MaskReg)
.addReg(MaskReg)
.setMIFlag(MachineInstr::MIFlag::NoMerge);
@@ -1003,9 +1008,9 @@ bool X86InstrInfo::expandCtSelectIntWithoutCMOV(MachineInstr &MI) const {
// Step 8: Final result: (src1 & mask) | (src2 & ~mask)
auto LI = BuildMI(*MBB, MI, DL, get(OrOp), DstReg)
- .addReg(DstReg)
- .addReg(MaskReg)
- .setMIFlag(MachineInstr::MIFlag::NoMerge);
+ .addReg(DstReg)
+ .addReg(MaskReg)
+ .setMIFlag(MachineInstr::MIFlag::NoMerge);
// Bundle all generated instructions for atomic execution before removing MI
auto BundleEnd = std::next(LI->getIterator());
@@ -1014,11 +1019,12 @@ bool X86InstrInfo::expandCtSelectIntWithoutCMOV(MachineInstr &MI) const {
finalizeBundle(*MBB, BundleStart, BundleEnd);
}
- // TODO: Optimization opportunity - The register allocator may choose callee-saved
- // registers (e.g., %ebx, %esi) for TmpByteReg/TmpMaskReg, causing unnecessary
- // save/restore overhead. Consider constraining these to caller-saved register
- // classes (e.g., GR8_AL, GR32_CallSaved) in the TableGen definitions to improve
- // constant-time performance by eliminating prologue/epilogue instructions.
+ // TODO: Optimization opportunity - The register allocator may choose
+ // callee-saved registers (e.g., %ebx, %esi) for TmpByteReg/TmpMaskReg,
+ // causing unnecessary save/restore overhead. Consider constraining these to
+ // caller-saved register classes (e.g., GR8_AL, GR32_CallSaved) in the
+ // TableGen definitions to improve constant-time performance by eliminating
+ // prologue/epilogue instructions.
// Remove the original pseudo instruction
MI.eraseFromParent();
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index a776b5491..7e1df40d3 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -621,7 +621,7 @@ void X86PassConfig::addPreEmitPass2() {
(TT.isOSDarwin() &&
(M->getFunction("objc_retainAutoreleasedReturnValue") ||
M->getFunction("objc_unsafeClaimAutoreleasedReturnValue"))) ||
- F.hasFnAttribute("ct-select");
+ F.hasFnAttribute("ct-select");
}));
// Analyzes and emits pseudos to support Win x64 Unwind V2. This pass must run
``````````
</details>
https://github.com/llvm/llvm-project/pull/164045
More information about the cfe-commits
mailing list