-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[CT] Updated CT X86 test for the LLVM 21 changes #164045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* splits vector and scalar handling for ctselect pseudo expansion
Implement constant time logic for integers on non-CMOV capable targets. - Only promote i8 to i32 when CMOV available, use native 8-bit otherwise - Add post-RA expansion for CTSELECT_I386_GR* pseudos with temp registers
Previously, in some cases, multiple patterns could match depending on what attributes where used. Now we are solely relying on the hasCMOV. Clarified a comment about why we are not widening 8-bit values in non-cmov context.
Add post-RA expansion for CTSELECT on i386 targets that lack CMOV support. Uses CMOV when available for optimal performance, falls back to bundled bitwise operations for constant-time guarantees on legacy targets.
Typical sequence was: 1. Load fp from mem -> fp reg 2. Store fp -> stack 3. Load int from stack New sequence is instead: 1. Load from stack (as int) This improves codegen for: - Global floating point variables - Global floating point constants - Stack based floating point variables
You can test this locally with the following command: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
View the diff from clang-format here.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
|
this was on accident, really sorry! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Specific
ctselect
related test, from the changes relating done in LLVM 21