Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3b8998e
[Xtensa] Add Boolean Extension feature
maciej-czekaj Mar 27, 2023
f934f9d
[Xtensa] Refactor loadImmediate
maciej-czekaj Mar 27, 2023
53304b4
[Xtensa] Implement BRegFixupPass
maciej-czekaj Mar 27, 2023
fb1ae9c
[Xtensa] Add LLVM tests for Boolean Extension
maciej-czekaj Mar 27, 2023
3b44416
[Xtensa] Separate directory for Clang CodeGen tests
maciej-czekaj Mar 27, 2023
ca61c69
[Xtensa] Add ABI test for xtbool
maciej-czekaj Mar 27, 2023
a1cd13f
[Xtensa] Implement conditional move instrinsics
maciej-czekaj Mar 27, 2023
9cd23f0
[Xtensa] Add basic float intrinsics
maciej-czekaj Mar 27, 2023
f51bb88
[Xtensa] Implement remaining floating point intrinsics
maciej-czekaj Mar 27, 2023
c2eecdf
[Xtensa] Add Cannonlake CPU
maciej-czekaj Mar 27, 2023
c95f0a2
[Xtensa] Make assembler output compatible with GAS
maciej-czekaj Mar 27, 2023
d5b18b1
[Xtensa] Add HIFI3 intrinsic functions
maciej-czekaj Jun 29, 2023
ca82094
[Xtensa] Add HIFI3 register classes
maciej-czekaj Jun 29, 2023
839d585
[Xtensa] Add HIFI3 target feature
maciej-czekaj Jun 29, 2023
0edb036
[Xtensa] Add HIFI3 instructions
maciej-czekaj Jun 30, 2023
879cf11
[Xtensa] Add support for boolean vectors
maciej-czekaj Jun 29, 2023
fd83061
[Xtensa] Add HIFI3 instruction lowering
maciej-czekaj Jun 30, 2023
1f73308
[Xtensa] Fix alignment in LowerVACOPY()
maciej-czekaj Jun 30, 2023
b4185cf
[Xtensa] Add HIFI3 instruction selection patterns
maciej-czekaj Jun 29, 2023
73545b3
[Xtensa] Add codegen tests for vector operators
maciej-czekaj Jun 29, 2023
89f9f17
[Xtensa] Add codegen tests for bit vectors
maciej-czekaj Jun 29, 2023
3b83722
[Xtensa] Add codegen support for HIFI3 intrinsics
maciej-czekaj Jun 29, 2023
3814e83
[Xtensa] Support bit vectors in BRegFixupPass
maciej-czekaj Jun 29, 2023
260da9b
[Xtensa] Remove unsspported intrinsic xt_conjc_s
maciej-czekaj Jun 29, 2023
bea17fb
[Xtensa] Add HIFI3 intrinsic definitions to clang
maciej-czekaj Jun 29, 2023
469a8c7
[Xtensa] Add constant checks for HIFI3 intrinsics
maciej-czekaj Jun 29, 2023
4afb827
[Xtensa] Add HIFI3 intrinsics to Clang codegen
maciej-czekaj Jun 29, 2023
cc070fc
[Xtensa] Fix xt_lsxp builtin definition
maciej-czekaj Jun 29, 2023
379c3e6
[Xtensa] Support bool vectors in LLVM calls
maciej-czekaj Jun 29, 2023
e0474f4
[Xtensa] Support HIFI3 vectors in LLVM calls
maciej-czekaj Jun 29, 2023
08d3319
[Xtensa] Add --text-section-literals option
maciej-czekaj Jun 29, 2023
7956407
[Xtensa] Add vector conversion builtins
maciej-czekaj Aug 4, 2023
ad588f9
[Xtensa] Add HIFI3 C types and intrinsics
maciej-czekaj Jun 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[Xtensa] Add support for boolean vectors
Xtensa architecture uses v2i1 (BR2 reg class) and v4i1 (BR4 reg class) boolean vectors as arguments for HIFI instructions:
 - vector compare, e.g.: AE_EQ16X4
 - vector conditional move, e.g: AE_MOVT16X4
  • Loading branch information
maciej-czekaj committed Aug 4, 2023
commit 879cf117854e52401ed7227b345433fed95a57c4
2 changes: 2 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class CCIfFeature<string Feature, CCAction A>:
def RetCC_Xtensa : CallingConv<[
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
CCIfFeature<"Boolean",CCIfType<[v1i1], CCAssignToReg<[B0]>>>,
CCIfFeature<"Boolean",CCIfType<[v2i1], CCAssignToReg<[B0_B1]>>>,
CCIfFeature<"Boolean",CCIfType<[v4i1], CCAssignToReg<[B0_B1_B2_B3]>>>,
CCIfType<[f32], CCBitConvertToType<i32>>,

//First two return values go in a2, a3, a4, a5
Expand Down
156 changes: 146 additions & 10 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,20 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,

if (Subtarget.hasBoolean()) {
addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);
addRegisterClass(MVT::v2i1, &Xtensa::BR2RegClass);
addRegisterClass(MVT::v4i1, &Xtensa::BR4RegClass);
setOperationAction(ISD::Constant, MVT::v2i1, Expand);
setOperationAction(ISD::Constant, MVT::v1i1, Expand);
for (MVT VT : MVT::integer_valuetypes()) {
setLoadExtAction(ISD::SEXTLOAD, VT, MVT::v1i1, Promote);
setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::v1i1, Promote);
setLoadExtAction(ISD::EXTLOAD, VT, MVT::v1i1, Promote);
}
}
setTargetDAGCombine(ISD::STORE);
setTargetDAGCombine(ISD::BITCAST);
setTargetDAGCombine(ISD::EXTRACT_SUBVECTOR);

setOperationAction(ISD::STORE, MVT::v1i1, Legal);
setOperationAction(ISD::STORE, MVT::v2i1, Legal);
setOperationAction(ISD::STORE, MVT::v4i1, Legal);
setOperationAction(ISD::LOAD, MVT::v1i1, Legal);
setOperationAction(ISD::LOAD, MVT::v2i1, Legal);
setOperationAction(ISD::LOAD, MVT::v4i1, Legal);

// Set up special registers.
setStackPointerRegisterToSaveRestore(Xtensa::SP);
Expand Down Expand Up @@ -104,7 +111,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,

// Used by legalize types to correctly generate the setcc result.
// AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
setOperationPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
if (!Subtarget.hasBoolean())
setOperationPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32);

setOperationAction(ISD::BR_CC, MVT::i32, Legal);
Expand Down Expand Up @@ -374,6 +382,14 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,
computeRegisterProperties(STI.getRegisterInfo());
}

EVT XtensaTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
EVT VT) const {
if (!VT.isVector()) {
return MVT::i32;
}
return VT.changeVectorElementTypeToInteger();
}

/// Return the register type for a given MVT
MVT XtensaTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
Expand Down Expand Up @@ -707,6 +723,91 @@ static SDValue PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG,
LHS, RHS, Dest);
}

static SDValue PerformBITCASTCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const XtensaSubtarget &Subtarget) {
// (vNi1 (bitcast (iN (trunc i32)))) -> (vNi1 (xtensa_bitcast i32))
SDLoc DL(N);
SDValue Op = N->getOperand(0);

if (N->getOpcode() != ISD::BITCAST || Op.getOpcode() != ISD::TRUNCATE)
return SDValue();

SDValue Int = Op.getOperand(0);
llvm::EVT BoolVT = N->getValueType(0);

if (!BoolVT.isVector() || BoolVT.getVectorElementType() != MVT::i1 ||
Int.getValueType() != MVT::i32)
return SDValue();

SDValue Trunc = DAG.getNode(XtensaISD::TRUNC, DL, BoolVT, Int);

return Trunc;
}

static SDValue
PerformExtractSubvectorCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const XtensaSubtarget &Subtarget) {
// (vNi1 (extract_subvector (v8i1 (load x))) -> (vNi1 (load x))
SDLoc DL(N);
SDValue Load = N->getOperand(0);

if (N->getOpcode() != ISD::EXTRACT_SUBVECTOR)
return SDValue();

EVT LoadVT = Load.getValueType();
EVT BoolVT = N->getValueType(0);

if (!BoolVT.isVector() || BoolVT.getVectorElementType() != MVT::i1)
return SDValue();

if (Load.getOpcode() != ISD::LOAD)
return SDValue();

LoadSDNode *LdNode = cast<LoadSDNode>(Load.getNode());

if (!LoadVT.isVector() || LoadVT.getVectorElementType() != MVT::i1)
return SDValue();

SDValue NewLoad =
DAG.getLoad(BoolVT, DL, LdNode->getChain(), LdNode->getBasePtr(),
LdNode->getPointerInfo(), LdNode->getOriginalAlign(),
LdNode->getMemOperand()->getFlags());

return NewLoad;
}
static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const XtensaSubtarget &Subtarget) {
// (store (v8i1 (concat_vector (vNi1 elt) undef )) addr off)
// -> (store (vNi1 elt) addr off)
SDLoc DL(N);

if (N->getOpcode() != ISD::STORE)
return SDValue();

StoreSDNode *StNode = cast<StoreSDNode>(N);

SDValue Concat = N->getOperand(1);
EVT BoolVT = Concat.getValueType();

if ((Concat.getOpcode() != ISD::CONCAT_VECTORS) || !BoolVT.isVector() ||
(BoolVT.getVectorElementType() != MVT::i1))
return SDValue();

SDValue Val = Concat.getNode()->getOperand(0);
EVT ValVT = Val.getValueType();

if (!ValVT.isVector() || ValVT.getVectorElementType() != MVT::i1 ||
ValVT.getSizeInBits() > 8) {
return SDValue();
}

return DAG.getStore(StNode->getChain(), DL, Val, StNode->getBasePtr(),
StNode->getMemOperand());
}

SDValue XtensaTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
Expand All @@ -723,6 +824,12 @@ SDValue XtensaTargetLowering::PerformDAGCombine(SDNode *N,
return PerformHWLoopCombine(N, DAG, DCI, Subtarget);
case ISD::BRCOND:
return PerformBRCONDCombine(N, DAG, DCI, Subtarget);
case ISD::BITCAST:
return PerformBITCASTCombine(N, DAG, DCI, Subtarget);
case ISD::EXTRACT_SUBVECTOR:
return PerformExtractSubvectorCombine(N, DAG, DCI, Subtarget);
case ISD::STORE:
return PerformSTORECombine(N, DAG, DCI, Subtarget);
}

return SDValue();
Expand All @@ -745,6 +852,12 @@ static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11,
Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15};

ArrayRef<MCPhysReg> BR2Regs(Xtensa::BR2RegClass.begin(),
Xtensa::BR2RegClass.end());

ArrayRef<MCPhysReg> BR4Regs(Xtensa::BR4RegClass.begin(),
Xtensa::BR4RegClass.end());

if (ArgFlags.isByVal()) {
Align ByValAlign = ArgFlags.getNonZeroByValAlign();
unsigned Offset = State.AllocateStack(ArgFlags.getByValSize(), ByValAlign);
Expand Down Expand Up @@ -793,6 +906,11 @@ static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
LocVT = MVT::i32;
} else if (ValVT == MVT::v1i1) {
Reg = State.AllocateReg(BoolRegs);
} else if (ValVT == MVT::v2i1) {
Reg = State.AllocateReg(BR2Regs);
LocVT = ValVT;
} else if (ValVT == MVT::v4i1) {
Reg = State.AllocateReg(BR4Regs);
LocVT = ValVT;
} else
llvm_unreachable("Cannot handle this ValVT.");
Expand Down Expand Up @@ -890,6 +1008,10 @@ SDValue XtensaTargetLowering::LowerFormalArguments(
RC = &Xtensa::ARRegClass;
} else if (RegVT == MVT::v1i1) {
RC = &Xtensa::BRRegClass;
} else if (RegVT == MVT::v2i1) {
RC = &Xtensa::BR2RegClass;
} else if (RegVT == MVT::v4i1) {
RC = &Xtensa::BR4RegClass;
} else
llvm_unreachable("RegVT not supported by FormalArguments Lowering");

Expand Down Expand Up @@ -3354,7 +3476,8 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
}
return MBB;
}
case Xtensa::MOVBA_P: {
case Xtensa::MOVBA_P:
case Xtensa::MOVBA2_P: {
const TargetRegisterClass *AR = getRegClassFor(MVT::i32);

Register Dst1 = MRI.createVirtualRegister(AR);
Expand All @@ -3365,8 +3488,21 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
/*
MOVBA_P2 Breg, Dst1, Dest2, Src
*/

BuildMI(*MBB, MI, DL, TII.get(Xtensa::MOVBA_P2), Breg.getReg())
unsigned TargetOpcode;
switch (MI.getOpcode()) {
case Xtensa::MOVBA_P:
TargetOpcode = Xtensa::MOVBA_P2;
break;
case Xtensa::MOVBA2_P:
TargetOpcode = Xtensa::MOVBA2_P2;
break;
case Xtensa::MOVBA4_P:
TargetOpcode = Xtensa::MOVBA4_P2;
break;
default:
llvm_unreachable("Unknown opcode");
}
BuildMI(*MBB, MI, DL, TII.get(TargetOpcode), Breg.getReg())
.addReg(Dst1, RegState::Define | RegState::EarlyClobber)
.addReg(Dst2, RegState::Define | RegState::EarlyClobber)
.addReg(Src.getReg());
Expand Down
41 changes: 38 additions & 3 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -990,22 +990,57 @@ let Predicates = [HasBoolean] in {
"!movba $r, $s", []> {
let usesCustomInserter = 1;
let Defs = [BREG];
//let Uses = [BREG];
}

def MOVBA2_P2: Pseudo<(outs BR2:$r, AR:$x, AR:$y), (ins AR:$s),
"!movba $r, $x, $y, $s", []> {
let Defs = [BREG];
}

def MOVBA2_P: Pseudo<(outs BR2:$r), (ins AR:$s),
"!movba2 $r, $s", []> {
let usesCustomInserter = 1;
let Defs = [BREG];
}

def MOVBA4_P2: Pseudo<(outs BR4:$r, AR:$x, AR:$y), (ins AR:$s),
"!movba4 $r, $x, $y, $s", []> {
let Defs = [BREG];
}

def MOVBA4_P: Pseudo<(outs BR4:$r), (ins AR:$s),
"!movba4 $r, $s", []> {
let usesCustomInserter = 1;
let Defs = [BREG];
}

def EXTUI_BR_P: Pseudo<(outs AR:$r), (ins AR:$s, BR:$b),
"!extui_br $r, $s, $b", []>;
def EXTUI_BR2_P: Pseudo<(outs AR:$r), (ins AR:$s, BR2:$b),
"!extui_br2 $r, $s, $b", []>;
def EXTUI_BR4_P: Pseudo<(outs AR:$r), (ins AR:$s, BR4:$b),
"!extui_br4 $r, $s, $b", []>;
def SLLI_BR_P: Pseudo<(outs AR:$r), (ins AR:$s, BR:$b),
"!slli_br $r, $s, $b", []>;

def : Pat<(v1i1 (build_vector AR:$a)), (MOVBA_P AR:$a)>;

def : Pat<(v1i1 (scalar_to_vector AR:$a)), (MOVBA_P AR:$a)>;

def : Pat<(v2i1 (build_vector AR:$a, AR:$b)),
(MOVBA2_P (OR AR:$a, (SLLI AR:$b, (i32 1))))>;

def : Pat<(v2i1 (Xtensa_trunc AR:$s)), (MOVBA2_P AR:$s)>;
def : Pat<(v4i1 (Xtensa_trunc AR:$s)), (MOVBA4_P AR:$s)>;

def : Pat<(i32 (vector_extract (v1i1 BR:$b), (i32 0))),
(EXTUI_BR_P (RSR BREG), BR:$b)>;

def : Pat<(v1i1 (load addr_ish1:$addr)), (MOVBA_P (L8UI mem8:$addr))>;
def : Pat<(v2i1 (load addr_ish1:$addr)), (MOVBA2_P (L8UI mem8:$addr))>;
def : Pat<(v4i1 (load addr_ish1:$addr)), (MOVBA4_P (L8UI mem8:$addr))>;

def : Pat<(store BR:$b, addr_ish1:$addr), (S8I (EXTUI_BR_P (RSR BREG), BR:$b), mem32:$addr)>;
def : Pat<(store BR2:$b, addr_ish1:$addr), (S8I (EXTUI_BR2_P (RSR BREG), BR2:$b), mem32:$addr)>;
def : Pat<(store BR4:$b, addr_ish1:$addr), (S8I (EXTUI_BR4_P (RSR BREG), BR4:$b), mem32:$addr)>;

def SPILL_BOOL: Pseudo<(outs), (ins BR:$b, mem8:$mem),
"!spill_bool $b, $mem",[]> {
Expand Down