From d37939680d08589fcdbbf9277a17ac16e0ff7dc2 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Fri, 28 Jun 2024 09:48:48 +0300 Subject: [PATCH 1/7] [Xtensa] Implement lowering SELECT_CC, SETCC. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 186 ++++++++++++++ llvm/lib/Target/Xtensa/XtensaISelLowering.h | 28 ++- llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 32 +++ llvm/lib/Target/Xtensa/XtensaOperators.td | 9 + llvm/test/CodeGen/Xtensa/select-cc.ll | 125 ++++++++++ llvm/test/CodeGen/Xtensa/setcc.ll | 232 ++++++++++++++++++ llvm/utils/UpdateTestChecks/asm.py | 8 + 7 files changed, 619 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/Xtensa/select-cc.ll create mode 100644 llvm/test/CodeGen/Xtensa/setcc.ll diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 65097930125040..8f19ae1b8e672c 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -90,6 +90,26 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, setOperationAction(ISD::BR_CC, MVT::i64, Expand); setOperationAction(ISD::BR_CC, MVT::f32, Expand); + // Used by legalize types to correctly generate the setcc result. + // AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); + setOperationPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); + setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32); + + setOperationAction(ISD::BR_CC, MVT::i32, Legal); + setOperationAction(ISD::BR_CC, MVT::i64, Expand); + + setOperationAction(ISD::SELECT, MVT::i32, Expand); + setOperationAction(ISD::SELECT, MVT::i64, Expand); + + setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); + setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); + + setOperationAction(ISD::SETCC, MVT::i32, Custom); + setOperationAction(ISD::SETCC, MVT::i64, Expand); + + // make BRCOND legal, its actually only legal for a subset of conds + setOperationAction(ISD::BRCOND, MVT::Other, Legal); + // Implement custom stack allocations setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); // Implement custom stack save and restore @@ -514,6 +534,38 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps); } +SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, + SelectionDAG &DAG) const { + SDLoc DL(Op); + EVT Ty = Op.getOperand(0).getValueType(); + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + SDValue TrueValue = Op.getOperand(2); + SDValue FalseValue = Op.getOperand(3); + ISD::CondCode CC = cast(Op->getOperand(4))->get(); + SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32); + + // Wrap select nodes + return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, + FalseValue, TargetCC); +} + +SDValue XtensaTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { + SDLoc DL(Op); + EVT Ty = Op.getOperand(0).getValueType(); + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32); + + // Expand to target SELECT_CC + SDValue TrueValue = DAG.getConstant(1, DL, Op.getValueType()); + SDValue FalseValue = DAG.getConstant(0, DL, Op.getValueType()); + + return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, + FalseValue, TargetCC); +} + SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, SelectionDAG &DAG) const { const ConstantSDNode *CN = cast(Op); @@ -676,6 +728,10 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op, return LowerJumpTable(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(cast(Op), DAG); + case ISD::SETCC: + return LowerSETCC(Op, DAG); + case ISD::SELECT_CC: + return LowerSELECT_CC(Op, DAG); case ISD::STACKSAVE: return LowerSTACKSAVE(Op, DAG); case ISD::STACKRESTORE: @@ -697,6 +753,136 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const { return "XtensaISD::PCREL_WRAPPER"; case XtensaISD::RET: return "XtensaISD::RET"; + case XtensaISD::SELECT: + return "XtensaISD::SELECT"; + case XtensaISD::SELECT_CC: + return "XtensaISD::SELECT_CC"; } return nullptr; } + +//===----------------------------------------------------------------------===// +// Custom insertion +//===----------------------------------------------------------------------===// + +static int GetBranchKind(int Cond, bool &BrInv) { + switch (Cond) { + case ISD::SETEQ: + case ISD::SETOEQ: + case ISD::SETUEQ: + return Xtensa::BEQ; + case ISD::SETNE: + case ISD::SETONE: + case ISD::SETUNE: + return Xtensa::BNE; + case ISD::SETLT: + case ISD::SETOLT: + return Xtensa::BLT; + case ISD::SETLE: + case ISD::SETOLE: + BrInv = true; + return Xtensa::BGE; + case ISD::SETGT: + case ISD::SETOGT: + BrInv = true; + return Xtensa::BLT; + case ISD::SETGE: + case ISD::SETOGE: + return Xtensa::BGE; + case ISD::SETULT: + return Xtensa::BLTU; + case ISD::SETULE: + BrInv = true; + return Xtensa::BGEU; + case ISD::SETUGT: + BrInv = true; + return Xtensa::BLTU; + case ISD::SETUGE: + return Xtensa::BGEU; + default: + return -1; + } +} + +MachineBasicBlock * +XtensaTargetLowering::emitSelectCC(MachineInstr &MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + DebugLoc DL = MI.getDebugLoc(); + + MachineOperand &LHS = MI.getOperand(1); + MachineOperand &RHS = MI.getOperand(2); + MachineOperand &TrueValue = MI.getOperand(3); + MachineOperand &FalseValue = MI.getOperand(4); + MachineOperand &Cond = MI.getOperand(5); + + // To "insert" a SELECT_CC instruction, we actually have to insert + // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi + // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue + // is passed from MMB and FalseValue is passed from CopyMBB. + // MBB + // | \ + // | CopyMBB + // | / + // SinkMBB + // The incoming instruction knows the + // destination vreg to set, the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = ++MBB->getIterator(); + + MachineFunction *F = MBB->getParent(); + MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB); + + F->insert(It, CopyMBB); + F->insert(It, SinkMBB); + + // Transfer the remainder of MBB and its successor edges to SinkMBB. + SinkMBB->splice(SinkMBB->begin(), MBB, + std::next(MachineBasicBlock::iterator(MI)), MBB->end()); + SinkMBB->transferSuccessorsAndUpdatePHIs(MBB); + + MBB->addSuccessor(CopyMBB); + MBB->addSuccessor(SinkMBB); + + bool BrInv = false; + int BrKind = GetBranchKind(Cond.getImm(), BrInv); + if (BrInv) { + BuildMI(MBB, DL, TII.get(BrKind)) + .addReg(RHS.getReg()) + .addReg(LHS.getReg()) + .addMBB(SinkMBB); + } else { + BuildMI(MBB, DL, TII.get(BrKind)) + .addReg(LHS.getReg()) + .addReg(RHS.getReg()) + .addMBB(SinkMBB); + } + + CopyMBB->addSuccessor(SinkMBB); + + // SinkMBB: + // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ] + // ... + + BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI), + MI.getOperand(0).getReg()) + .addReg(FalseValue.getReg()) + .addMBB(CopyMBB) + .addReg(TrueValue.getReg()) + .addMBB(MBB); + + MI.eraseFromParent(); // The pseudo instruction is gone now. + return SinkMBB; +} + +MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter( + MachineInstr &MI, MachineBasicBlock *MBB) const { + switch (MI.getOpcode()) { + case Xtensa::SELECT: + return emitSelectCC(MI, MBB); + default: + report_fatal_error("Unexpected instr type to insert"); + } +} diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h index 23a0217daaa96d..8a4491c38db5fe 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -33,7 +33,14 @@ enum { // Wraps a TargetGlobalAddress that should be loaded using PC-relative // accesses. Operand 0 is the address. PCREL_WRAPPER, - RET + RET, + + // Selects between operand 0 and operand 1. Operand 2 is the + // mask of condition-code values for which operand 0 should be + // chosen over operand 1; it has the same form as BR_CCMASK. + // Operand 3 is the flag operand. + SELECT, + SELECT_CC }; } @@ -44,6 +51,13 @@ class XtensaTargetLowering : public TargetLowering { explicit XtensaTargetLowering(const TargetMachine &TM, const XtensaSubtarget &STI); + EVT getSetCCResultType(const DataLayout &, LLVMContext &, + EVT VT) const override { + if (!VT.isVector()) + return MVT::i32; + return VT.changeVectorElementTypeToInteger(); + } + bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; const char *getTargetNodeName(unsigned Opcode) const override; @@ -71,6 +85,10 @@ class XtensaTargetLowering : public TargetLowering { const XtensaSubtarget &getSubtarget() const { return Subtarget; } + MachineBasicBlock * + EmitInstrWithCustomInserter(MachineInstr &MI, + MachineBasicBlock *BB) const override; + private: const XtensaSubtarget &Subtarget; @@ -86,6 +104,10 @@ class XtensaTargetLowering : public TargetLowering { SDValue LowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const; + SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; + + SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const; @@ -95,6 +117,10 @@ class XtensaTargetLowering : public TargetLowering { SDValue getAddrPCRel(SDValue Op, SelectionDAG &DAG) const; CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; + + // Implement EmitInstrWithCustomInserter for individual operation types. + MachineBasicBlock *emitSelectCC(MachineInstr &MI, + MachineBasicBlock *BB) const; }; } // end namespace llvm diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td index f68d20dcdd54ab..9e3a35808d0b60 100644 --- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td +++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -425,6 +425,29 @@ def : Pat<(brcc SETLE, AR:$s, AR:$t, bb:$target), def : Pat<(brcc SETULE, AR:$s, AR:$t, bb:$target), (BGEU AR:$t, AR:$s, bb:$target)>; +def : Pat<(brcond (i32 (seteq AR:$s, AR:$t)), bb:$target), + (BEQ AR:$s, AR:$t, bb:$target)>; +def : Pat<(brcond (i32 (setne AR:$s, AR:$t)), bb:$target), + (BNE AR:$s, AR:$t, bb:$target)>; +def : Pat<(brcond (i32 (setge AR:$s, AR:$t)), bb:$target), + (BGE AR:$s, AR:$t, bb:$target)>; +def : Pat<(brcond (i32 (setle AR:$s, AR:$t)), bb:$target), + (BLT AR:$s, AR:$t, bb:$target)>; +def : Pat<(brcond (i32 (setuge AR:$s, AR:$t)), bb:$target), + (BGEU AR:$s, AR:$t, bb:$target)>; +def : Pat<(brcond (i32 (setult AR:$s, AR:$t)), bb:$target), + (BLTU AR:$s, AR:$t, bb:$target)>; +def : Pat<(brcond (i32 (setgt AR:$s, AR:$t)), bb:$target), + (BLT AR:$t, AR:$s, bb:$target)>; +def : Pat<(brcond (i32 (setugt AR:$s, AR:$t)), bb:$target), + (BLTU AR:$t, AR:$s, bb:$target)>; +def : Pat<(brcond (i32 (setle AR:$s, AR:$t)), bb:$target), + (BGE AR:$t, AR:$s, bb:$target)>; +def : Pat<(brcond (i32 (setule AR:$s, AR:$t)), bb:$target), + (BGEU AR:$t, AR:$s, bb:$target)>; + +def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>; + //===----------------------------------------------------------------------===// // Call and jump instructions //===----------------------------------------------------------------------===// @@ -574,3 +597,12 @@ let Defs = [SP], Uses = [SP] in { "#ADJCALLSTACKUP", [(Xtensa_callseq_end timm:$amt1, timm:$amt2)]>; } + +//===----------------------------------------------------------------------===// +// Generic select instruction +//===----------------------------------------------------------------------===// +let usesCustomInserter = 1 in { + def SELECT : Pseudo<(outs AR:$dst), (ins AR:$lhs, AR:$rhs, AR:$t, AR:$f, i32imm:$cond), + "!select $dst, $lhs, $rhs, $t, $f, $cond", + [(set AR:$dst, (Xtensa_select_cc AR:$lhs, AR:$rhs, AR:$t, AR:$f, imm:$cond))]>; +} diff --git a/llvm/lib/Target/Xtensa/XtensaOperators.td b/llvm/lib/Target/Xtensa/XtensaOperators.td index 88d3c9dfe7fd83..aab2d2d2bbe79d 100644 --- a/llvm/lib/Target/Xtensa/XtensaOperators.td +++ b/llvm/lib/Target/Xtensa/XtensaOperators.td @@ -19,6 +19,11 @@ def SDT_XtensaWrapPtr : SDTypeProfile<1, 1, def SDT_XtensaBrJT : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>; + +def SDT_XtensaSelectCC : SDTypeProfile<1, 5, + [SDTCisSameAs<0, 1>, + SDTCisSameAs<2, 3>, + SDTCisVT<5, i32>]>; //===----------------------------------------------------------------------===// // Node definitions //===----------------------------------------------------------------------===// @@ -38,3 +43,7 @@ def Xtensa_callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XtensaCallSeqEnd, SDNPOutGlue]>; def Xtensa_brjt: SDNode<"XtensaISD::BR_JT", SDT_XtensaBrJT, [SDNPHasChain]>; + +def Xtensa_select : SDNode<"XtensaISD::SELECT", SDTSelect>; +def Xtensa_select_cc: SDNode<"XtensaISD::SELECT_CC", SDT_XtensaSelectCC, + [SDNPInGlue]>; diff --git a/llvm/test/CodeGen/Xtensa/select-cc.ll b/llvm/test/CodeGen/Xtensa/select-cc.ll new file mode 100644 index 00000000000000..6073ee7cc25586 --- /dev/null +++ b/llvm/test/CodeGen/Xtensa/select-cc.ll @@ -0,0 +1,125 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=xtensa -disable-block-placement -verify-machineinstrs < %s \ +; RUN: | FileCheck %s + +define signext i32 @foo(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: foo: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: beq a2, a8, .LBB0_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: bne a2, a8, .LBB0_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_4: +; CHECK-NEXT: bltu a8, a2, .LBB0_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_6: +; CHECK-NEXT: bgeu a2, a8, .LBB0_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_8: +; CHECK-NEXT: bltu a2, a8, .LBB0_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_10: +; CHECK-NEXT: bgeu a8, a2, .LBB0_12 +; CHECK-NEXT: # %bb.11: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_12: +; CHECK-NEXT: blt a8, a2, .LBB0_14 +; CHECK-NEXT: # %bb.13: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_14: +; CHECK-NEXT: bge a2, a8, .LBB0_16 +; CHECK-NEXT: # %bb.15: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_16: +; CHECK-NEXT: blt a2, a8, .LBB0_18 +; CHECK-NEXT: # %bb.17: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_18: +; CHECK-NEXT: bge a8, a2, .LBB0_20 +; CHECK-NEXT: # %bb.19: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_20: +; CHECK-NEXT: movi a9, 1 +; CHECK-NEXT: blt a8, a9, .LBB0_22 +; CHECK-NEXT: # %bb.21: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_22: +; CHECK-NEXT: movi a9, -1 +; CHECK-NEXT: blt a9, a8, .LBB0_24 +; CHECK-NEXT: # %bb.23: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_24: +; CHECK-NEXT: movi a9, 1024 +; CHECK-NEXT: blt a9, a8, .LBB0_26 +; CHECK-NEXT: # %bb.25: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_26: +; CHECK-NEXT: movi a9, 2046 +; CHECK-NEXT: bltu a9, a8, .LBB0_28 +; CHECK-NEXT: # %bb.27: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB0_28: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp eq i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + + %val3 = load i32, ptr %b + %tst2 = icmp ne i32 %val2, %val3 + %val4 = select i1 %tst2, i32 %val2, i32 %val3 + + %val5 = load i32, ptr %b + %tst3 = icmp ugt i32 %val4, %val5 + %val6 = select i1 %tst3, i32 %val4, i32 %val5 + + %val7 = load i32, ptr %b + %tst4 = icmp uge i32 %val6, %val7 + %val8 = select i1 %tst4, i32 %val6, i32 %val7 + + %val9 = load i32, ptr %b + %tst5 = icmp ult i32 %val8, %val9 + %val10 = select i1 %tst5, i32 %val8, i32 %val9 + + %val11 = load i32, ptr %b + %tst6 = icmp ule i32 %val10, %val11 + %val12 = select i1 %tst6, i32 %val10, i32 %val11 + + %val13 = load i32, ptr %b + %tst7 = icmp sgt i32 %val12, %val13 + %val14 = select i1 %tst7, i32 %val12, i32 %val13 + + %val15 = load i32, ptr %b + %tst8 = icmp sge i32 %val14, %val15 + %val16 = select i1 %tst8, i32 %val14, i32 %val15 + + %val17 = load i32, ptr %b + %tst9 = icmp slt i32 %val16, %val17 + %val18 = select i1 %tst9, i32 %val16, i32 %val17 + + %val19 = load i32, ptr %b + %tst10 = icmp sle i32 %val18, %val19 + %val20 = select i1 %tst10, i32 %val18, i32 %val19 + + %val21 = load i32, ptr %b + %tst11 = icmp slt i32 %val21, 1 + %val22 = select i1 %tst11, i32 %val20, i32 %val21 + + %val23 = load i32, ptr %b + %tst12 = icmp sgt i32 %val21, -1 + %val24 = select i1 %tst12, i32 %val22, i32 %val23 + + %val25 = load i32, ptr %b + %tst13 = icmp sgt i32 %val25, 1024 + %val26 = select i1 %tst13, i32 %val24, i32 %val25 + + %val27 = load i32, ptr %b + %tst14 = icmp ugt i32 %val21, 2046 + %val28 = select i1 %tst14, i32 %val26, i32 %val27 + ret i32 %val28 +} diff --git a/llvm/test/CodeGen/Xtensa/setcc.ll b/llvm/test/CodeGen/Xtensa/setcc.ll new file mode 100644 index 00000000000000..a8557b2365a314 --- /dev/null +++ b/llvm/test/CodeGen/Xtensa/setcc.ll @@ -0,0 +1,232 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=xtensa-unkonwn-elf -O0 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f1: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: beq a2, a3, .LBB0_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp eq i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f2(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f2: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: blt a2, a3, .LBB1_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp slt i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f3(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f3: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bge a3, a2, .LBB2_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB2_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp sle i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f4(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f4: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: blt a3, a2, .LBB3_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp sgt i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f5(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f5: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bge a2, a3, .LBB4_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB4_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp sge i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f6(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f6: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bne a2, a3, .LBB5_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB5_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ne i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f7(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f7: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bltu a2, a3, .LBB6_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB6_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ult i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f8(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f8: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a3, a2, .LBB7_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB7_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ule i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f9(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f9: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bltu a3, a2, .LBB8_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB8_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ugt i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} + +define i32 @f10(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f10: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a2, a3, .LBB9_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB9_2: +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp uge i32 %a, %b + %res = zext i1 %cond to i32 + ret i32 %res +} diff --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py index f150098eaaeef4..3fa67e34e21d77 100644 --- a/llvm/utils/UpdateTestChecks/asm.py +++ b/llvm/utils/UpdateTestChecks/asm.py @@ -109,6 +109,13 @@ class string: flags=(re.M | re.S), ) +ASM_FUNCTION_XTENSA_RE = re.compile( + r'^_?(?P[^.:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n# %bb.0:\n' + r'(?P.*?)\n' + r'^\.Lfunc_end\d+:\n', # Match the end label + flags=(re.M | re.S) +) + ASM_FUNCTION_PPC_RE = re.compile( r"#[ \-\t]*Begin function (?P[^.:]+)\n" r".*?" @@ -579,6 +586,7 @@ def get_run_handler(triple): "nvptx": (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE), "loongarch32": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE), "loongarch64": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE), + "xtensa": (scrub_asm_avr, ASM_FUNCTION_XTENSA_RE), } handler = None best_prefix = "" From c42bf96eb6b22037c7d0391f18881962f3446ff9 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Wed, 3 Jul 2024 12:26:16 +0300 Subject: [PATCH 2/7] [Xtensa] Fix setcc test and remove redundant code. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 4 - llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 22 -- llvm/test/CodeGen/Xtensa/select-cc.ll | 259 +++++++++++------- llvm/test/CodeGen/Xtensa/setcc.ll | 1 - llvm/utils/UpdateTestChecks/asm.py | 8 - 5 files changed, 159 insertions(+), 135 deletions(-) diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 8f19ae1b8e672c..c9db99ca54f6f9 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -91,7 +91,6 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, setOperationAction(ISD::BR_CC, MVT::f32, Expand); // Used by legalize types to correctly generate the setcc result. - // AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); setOperationPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32); @@ -107,9 +106,6 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SETCC, MVT::i32, Custom); setOperationAction(ISD::SETCC, MVT::i64, Expand); - // make BRCOND legal, its actually only legal for a subset of conds - setOperationAction(ISD::BRCOND, MVT::Other, Legal); - // Implement custom stack allocations setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); // Implement custom stack save and restore diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td index 9e3a35808d0b60..2d8242ad2b5f2b 100644 --- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td +++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -425,28 +425,6 @@ def : Pat<(brcc SETLE, AR:$s, AR:$t, bb:$target), def : Pat<(brcc SETULE, AR:$s, AR:$t, bb:$target), (BGEU AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcond (i32 (seteq AR:$s, AR:$t)), bb:$target), - (BEQ AR:$s, AR:$t, bb:$target)>; -def : Pat<(brcond (i32 (setne AR:$s, AR:$t)), bb:$target), - (BNE AR:$s, AR:$t, bb:$target)>; -def : Pat<(brcond (i32 (setge AR:$s, AR:$t)), bb:$target), - (BGE AR:$s, AR:$t, bb:$target)>; -def : Pat<(brcond (i32 (setle AR:$s, AR:$t)), bb:$target), - (BLT AR:$s, AR:$t, bb:$target)>; -def : Pat<(brcond (i32 (setuge AR:$s, AR:$t)), bb:$target), - (BGEU AR:$s, AR:$t, bb:$target)>; -def : Pat<(brcond (i32 (setult AR:$s, AR:$t)), bb:$target), - (BLTU AR:$s, AR:$t, bb:$target)>; -def : Pat<(brcond (i32 (setgt AR:$s, AR:$t)), bb:$target), - (BLT AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcond (i32 (setugt AR:$s, AR:$t)), bb:$target), - (BLTU AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcond (i32 (setle AR:$s, AR:$t)), bb:$target), - (BGE AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcond (i32 (setule AR:$s, AR:$t)), bb:$target), - (BGEU AR:$t, AR:$s, bb:$target)>; - -def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>; //===----------------------------------------------------------------------===// // Call and jump instructions diff --git a/llvm/test/CodeGen/Xtensa/select-cc.ll b/llvm/test/CodeGen/Xtensa/select-cc.ll index 6073ee7cc25586..3a020ec4332333 100644 --- a/llvm/test/CodeGen/Xtensa/select-cc.ll +++ b/llvm/test/CodeGen/Xtensa/select-cc.ll @@ -1,125 +1,184 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -mtriple=xtensa -disable-block-placement -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -define signext i32 @foo(i32 signext %a, ptr %b) nounwind { -; CHECK-LABEL: foo: +define signext i32 @f_eq(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_eq: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: beq a2, a8, .LBB0_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: or a2, a8, a8 ; CHECK-NEXT: .LBB0_2: -; CHECK-NEXT: bne a2, a8, .LBB0_4 -; CHECK-NEXT: # %bb.3: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_4: -; CHECK-NEXT: bltu a8, a2, .LBB0_6 -; CHECK-NEXT: # %bb.5: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_6: -; CHECK-NEXT: bgeu a2, a8, .LBB0_8 -; CHECK-NEXT: # %bb.7: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_8: -; CHECK-NEXT: bltu a2, a8, .LBB0_10 -; CHECK-NEXT: # %bb.9: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_10: -; CHECK-NEXT: bgeu a8, a2, .LBB0_12 -; CHECK-NEXT: # %bb.11: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_12: -; CHECK-NEXT: blt a8, a2, .LBB0_14 -; CHECK-NEXT: # %bb.13: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_14: -; CHECK-NEXT: bge a2, a8, .LBB0_16 -; CHECK-NEXT: # %bb.15: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_16: -; CHECK-NEXT: blt a2, a8, .LBB0_18 -; CHECK-NEXT: # %bb.17: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_18: -; CHECK-NEXT: bge a8, a2, .LBB0_20 -; CHECK-NEXT: # %bb.19: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_20: -; CHECK-NEXT: movi a9, 1 -; CHECK-NEXT: blt a8, a9, .LBB0_22 -; CHECK-NEXT: # %bb.21: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_22: -; CHECK-NEXT: movi a9, -1 -; CHECK-NEXT: blt a9, a8, .LBB0_24 -; CHECK-NEXT: # %bb.23: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_24: -; CHECK-NEXT: movi a9, 1024 -; CHECK-NEXT: blt a9, a8, .LBB0_26 -; CHECK-NEXT: # %bb.25: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_26: -; CHECK-NEXT: movi a9, 2046 -; CHECK-NEXT: bltu a9, a8, .LBB0_28 -; CHECK-NEXT: # %bb.27: -; CHECK-NEXT: or a2, a8, a8 -; CHECK-NEXT: .LBB0_28: ; CHECK-NEXT: ret %val1 = load i32, ptr %b %tst1 = icmp eq i32 %a, %val1 %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val3 = load i32, ptr %b - %tst2 = icmp ne i32 %val2, %val3 - %val4 = select i1 %tst2, i32 %val2, i32 %val3 - - %val5 = load i32, ptr %b - %tst3 = icmp ugt i32 %val4, %val5 - %val6 = select i1 %tst3, i32 %val4, i32 %val5 +define signext i32 @f_ne(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_ne: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bne a2, a8, .LBB1_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp ne i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val7 = load i32, ptr %b - %tst4 = icmp uge i32 %val6, %val7 - %val8 = select i1 %tst4, i32 %val6, i32 %val7 +define signext i32 @f_ugt(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_ugt: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bltu a8, a2, .LBB2_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB2_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp ugt i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val9 = load i32, ptr %b - %tst5 = icmp ult i32 %val8, %val9 - %val10 = select i1 %tst5, i32 %val8, i32 %val9 +define signext i32 @f_uge(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_uge: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bgeu a2, a8, .LBB3_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp uge i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val11 = load i32, ptr %b - %tst6 = icmp ule i32 %val10, %val11 - %val12 = select i1 %tst6, i32 %val10, i32 %val11 +define signext i32 @f_ult(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_ult: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bltu a2, a8, .LBB4_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB4_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp ult i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val13 = load i32, ptr %b - %tst7 = icmp sgt i32 %val12, %val13 - %val14 = select i1 %tst7, i32 %val12, i32 %val13 +define signext i32 @f_ule(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_ule: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bgeu a8, a2, .LBB5_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB5_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp ule i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val15 = load i32, ptr %b - %tst8 = icmp sge i32 %val14, %val15 - %val16 = select i1 %tst8, i32 %val14, i32 %val15 +define signext i32 @f_sgt(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_sgt: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: blt a8, a2, .LBB6_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB6_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp sgt i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val17 = load i32, ptr %b - %tst9 = icmp slt i32 %val16, %val17 - %val18 = select i1 %tst9, i32 %val16, i32 %val17 +define signext i32 @f_sge(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_sge: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bge a2, a8, .LBB7_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB7_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp sge i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val19 = load i32, ptr %b - %tst10 = icmp sle i32 %val18, %val19 - %val20 = select i1 %tst10, i32 %val18, i32 %val19 +define signext i32 @f_slt(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_slt: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: blt a2, a8, .LBB8_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB8_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp slt i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val21 = load i32, ptr %b - %tst11 = icmp slt i32 %val21, 1 - %val22 = select i1 %tst11, i32 %val20, i32 %val21 +define signext i32 @f_sle(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_sle: +; CHECK: l32i a8, a3, 0 +; CHECK-NEXT: bge a8, a2, .LBB9_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 +; CHECK-NEXT: .LBB9_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp sle i32 %a, %val1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val23 = load i32, ptr %b - %tst12 = icmp sgt i32 %val21, -1 - %val24 = select i1 %tst12, i32 %val22, i32 %val23 +define signext i32 @f_slt_imm(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_slt_imm: +; CHECK: movi a8, 1 +; CHECK-NEXT: blt a2, a8, .LBB10_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: .LBB10_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp slt i32 %a, 1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val25 = load i32, ptr %b - %tst13 = icmp sgt i32 %val25, 1024 - %val26 = select i1 %tst13, i32 %val24, i32 %val25 +define signext i32 @f_sgt_imm(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_sgt_imm: +; CHECK: movi a8, -1 +; CHECK-NEXT: blt a8, a2, .LBB11_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: .LBB11_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp sgt i32 %a, -1 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 +} - %val27 = load i32, ptr %b - %tst14 = icmp ugt i32 %val21, 2046 - %val28 = select i1 %tst14, i32 %val26, i32 %val27 - ret i32 %val28 +define signext i32 @f_ult_imm(i32 signext %a, ptr %b) nounwind { +; CHECK-LABEL: f_ult_imm: +; CHECK: movi a8, 1024 +; CHECK-NEXT: bltu a2, a8, .LBB12_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: .LBB12_2: +; CHECK-NEXT: ret + %val1 = load i32, ptr %b + %tst1 = icmp ult i32 %a, 1024 + %val2 = select i1 %tst1, i32 %a, i32 %val1 + ret i32 %val2 } diff --git a/llvm/test/CodeGen/Xtensa/setcc.ll b/llvm/test/CodeGen/Xtensa/setcc.ll index a8557b2365a314..f3dccf0d1bdcc2 100644 --- a/llvm/test/CodeGen/Xtensa/setcc.ll +++ b/llvm/test/CodeGen/Xtensa/setcc.ll @@ -1,4 +1,3 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -mtriple=xtensa-unkonwn-elf -O0 | FileCheck %s define i32 @f1(i32 %a, i32 %b) nounwind { diff --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py index 3fa67e34e21d77..f150098eaaeef4 100644 --- a/llvm/utils/UpdateTestChecks/asm.py +++ b/llvm/utils/UpdateTestChecks/asm.py @@ -109,13 +109,6 @@ class string: flags=(re.M | re.S), ) -ASM_FUNCTION_XTENSA_RE = re.compile( - r'^_?(?P[^.:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n# %bb.0:\n' - r'(?P.*?)\n' - r'^\.Lfunc_end\d+:\n', # Match the end label - flags=(re.M | re.S) -) - ASM_FUNCTION_PPC_RE = re.compile( r"#[ \-\t]*Begin function (?P[^.:]+)\n" r".*?" @@ -586,7 +579,6 @@ def get_run_handler(triple): "nvptx": (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE), "loongarch32": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE), "loongarch64": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE), - "xtensa": (scrub_asm_avr, ASM_FUNCTION_XTENSA_RE), } handler = None best_prefix = "" From c697e00816b978dbfac6ef679628f8d4b32c0b45 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Sun, 7 Jul 2024 02:54:18 +0300 Subject: [PATCH 3/7] [Xtensa] Minor fixes, remove redundant code. Removed redundant operations promotions and actions. Also removed setcc lowering and redundant branch kind cases from GetBranchKind() function. Implemented additional br_cc tests. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 43 +----- llvm/lib/Target/Xtensa/XtensaISelLowering.h | 11 +- llvm/lib/Target/Xtensa/XtensaOperators.td | 1 - llvm/test/CodeGen/Xtensa/brcc.ll | 130 ++++++++++++++++-- 4 files changed, 127 insertions(+), 58 deletions(-) diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index c9db99ca54f6f9..901ec133d59229 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -85,26 +85,13 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, // indirect jump. setOperationAction(ISD::BR_JT, MVT::Other, Custom); - setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32); setOperationAction(ISD::BR_CC, MVT::i32, Legal); setOperationAction(ISD::BR_CC, MVT::i64, Expand); setOperationAction(ISD::BR_CC, MVT::f32, Expand); - // Used by legalize types to correctly generate the setcc result. - setOperationPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); - setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32); - - setOperationAction(ISD::BR_CC, MVT::i32, Legal); - setOperationAction(ISD::BR_CC, MVT::i64, Expand); - setOperationAction(ISD::SELECT, MVT::i32, Expand); - setOperationAction(ISD::SELECT, MVT::i64, Expand); - setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); - setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); - - setOperationAction(ISD::SETCC, MVT::i32, Custom); - setOperationAction(ISD::SETCC, MVT::i64, Expand); + setOperationAction(ISD::SETCC, MVT::i32, Expand); // Implement custom stack allocations setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); @@ -546,22 +533,6 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, FalseValue, TargetCC); } -SDValue XtensaTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { - SDLoc DL(Op); - EVT Ty = Op.getOperand(0).getValueType(); - SDValue LHS = Op.getOperand(0); - SDValue RHS = Op.getOperand(1); - ISD::CondCode CC = cast(Op.getOperand(2))->get(); - SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32); - - // Expand to target SELECT_CC - SDValue TrueValue = DAG.getConstant(1, DL, Op.getValueType()); - SDValue FalseValue = DAG.getConstant(0, DL, Op.getValueType()); - - return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, - FalseValue, TargetCC); -} - SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, SelectionDAG &DAG) const { const ConstantSDNode *CN = cast(Op); @@ -724,8 +695,6 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op, return LowerJumpTable(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(cast(Op), DAG); - case ISD::SETCC: - return LowerSETCC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::STACKSAVE: @@ -749,8 +718,6 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const { return "XtensaISD::PCREL_WRAPPER"; case XtensaISD::RET: return "XtensaISD::RET"; - case XtensaISD::SELECT: - return "XtensaISD::SELECT"; case XtensaISD::SELECT_CC: return "XtensaISD::SELECT_CC"; } @@ -764,26 +731,18 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const { static int GetBranchKind(int Cond, bool &BrInv) { switch (Cond) { case ISD::SETEQ: - case ISD::SETOEQ: - case ISD::SETUEQ: return Xtensa::BEQ; case ISD::SETNE: - case ISD::SETONE: - case ISD::SETUNE: return Xtensa::BNE; case ISD::SETLT: - case ISD::SETOLT: return Xtensa::BLT; case ISD::SETLE: - case ISD::SETOLE: BrInv = true; return Xtensa::BGE; case ISD::SETGT: - case ISD::SETOGT: BrInv = true; return Xtensa::BLT; case ISD::SETGE: - case ISD::SETOGE: return Xtensa::BGE; case ISD::SETULT: return Xtensa::BLTU; diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h index 8a4491c38db5fe..657756dc30950e 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -35,11 +35,10 @@ enum { PCREL_WRAPPER, RET, - // Selects between operand 0 and operand 1. Operand 2 is the - // mask of condition-code values for which operand 0 should be - // chosen over operand 1; it has the same form as BR_CCMASK. - // Operand 3 is the flag operand. - SELECT, + // Select with condition operator - This selects between a true value and + // a false value (ops #2 and #3) based on the boolean result of comparing + // the lhs and rhs (ops #0 and #1) of a conditional expression with the + // condition code in op #4 SELECT_CC }; } @@ -104,8 +103,6 @@ class XtensaTargetLowering : public TargetLowering { SDValue LowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const; - SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/Xtensa/XtensaOperators.td b/llvm/lib/Target/Xtensa/XtensaOperators.td index aab2d2d2bbe79d..93cd1c933dbde6 100644 --- a/llvm/lib/Target/Xtensa/XtensaOperators.td +++ b/llvm/lib/Target/Xtensa/XtensaOperators.td @@ -44,6 +44,5 @@ def Xtensa_callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XtensaCallSeqEnd, def Xtensa_brjt: SDNode<"XtensaISD::BR_JT", SDT_XtensaBrJT, [SDNPHasChain]>; -def Xtensa_select : SDNode<"XtensaISD::SELECT", SDTSelect>; def Xtensa_select_cc: SDNode<"XtensaISD::SELECT_CC", SDT_XtensaSelectCC, [SDNPInGlue]>; diff --git a/llvm/test/CodeGen/Xtensa/brcc.ll b/llvm/test/CodeGen/Xtensa/brcc.ll index 83f6dfd1aebc34..05e59d36993eda 100644 --- a/llvm/test/CodeGen/Xtensa/brcc.ll +++ b/llvm/test/CodeGen/Xtensa/brcc.ll @@ -1,10 +1,10 @@ ; RUN: llc -march=xtensa < %s | FileCheck %s -; CHECK-LABEL: brcc1: +; CHECK-LABEL: brcc_sgt: ; CHECK: bge a3, a2, .LBB0_2 ; CHECK: addi a2, a2, 4 ; CHECK: .LBB0_2: -define i32 @brcc1(i32 %a, i32 %b) nounwind { +define i32 @brcc_sgt(i32 %a, i32 %b) nounwind { entry: %wb = icmp sgt i32 %a, %b br i1 %wb, label %t1, label %t2 @@ -19,11 +19,11 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc2 +; CHECK-LABEL: brcc_ugt ; CHECK: bgeu a3, a2, .LBB1_2 ; CHECK: addi a2, a2, 4 ; CHECK: .LBB1_2: -define i32 @brcc2(i32 %a, i32 %b) nounwind { +define i32 @brcc_ugt(i32 %a, i32 %b) nounwind { entry: %wb = icmp ugt i32 %a, %b br i1 %wb, label %t1, label %t2 @@ -38,11 +38,11 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc3: +; CHECK-LABEL: brcc_sle: ; CHECK: blt a3, a2, .LBB2_2 ; CHECK: addi a2, a2, 4 ; CHECK: .LBB2_2: -define i32 @brcc3(i32 %a, i32 %b) nounwind { +define i32 @brcc_sle(i32 %a, i32 %b) nounwind { entry: %wb = icmp sle i32 %a, %b br i1 %wb, label %t1, label %t2 @@ -57,11 +57,11 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc4 +; CHECK-LABEL: brcc_ule ; CHECK: bltu a3, a2, .LBB3_2 ; CHECK: addi a2, a2, 4 ; CHECK: .LBB3_2: -define i32 @brcc4(i32 %a, i32 %b) nounwind { +define i32 @brcc_ule(i32 %a, i32 %b) nounwind { entry: %wb = icmp ule i32 %a, %b br i1 %wb, label %t1, label %t2 @@ -75,3 +75,117 @@ exit: %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] ret i32 %v } + +; CHECK-LABEL: brcc_eq: +; CHECK: bne a2, a3, .LBB4_2 +; CHECK: addi a2, a2, 4 +; CHECK: .LBB4_2: +define i32 @brcc_eq(i32 %a, i32 %b) nounwind { +entry: + %wb = icmp eq i32 %a, %b + br i1 %wb, label %t1, label %t2 +t1: + %t1v = add i32 %a, 4 + br label %exit +t2: + %t2v = add i32 %b, 8 + br label %exit +exit: + %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] + ret i32 %v +} + +; CHECK-LABEL: brcc_ne: +; CHECK: beq a2, a3, .LBB5_2 +; CHECK: addi a2, a2, 4 +; CHECK: .LBB5_2: +define i32 @brcc_ne(i32 %a, i32 %b) nounwind { +entry: + %wb = icmp ne i32 %a, %b + br i1 %wb, label %t1, label %t2 +t1: + %t1v = add i32 %a, 4 + br label %exit +t2: + %t2v = add i32 %b, 8 + br label %exit +exit: + %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] + ret i32 %v +} + +; CHECK-LABEL: brcc_ge: +; CHECK: blt a2, a3, .LBB6_2 +; CHECK: addi a2, a2, 4 +; CHECK: .LBB6_2: +define i32 @brcc_ge(i32 %a, i32 %b) nounwind { +entry: + %wb = icmp sge i32 %a, %b + br i1 %wb, label %t1, label %t2 +t1: + %t1v = add i32 %a, 4 + br label %exit +t2: + %t2v = add i32 %b, 8 + br label %exit +exit: + %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] + ret i32 %v +} + +; CHECK-LABEL: brcc_lt: +; CHECK: bge a2, a3, .LBB7_2 +; CHECK: addi a2, a2, 4 +; CHECK: .LBB7_2: +define i32 @brcc_lt(i32 %a, i32 %b) nounwind { +entry: + %wb = icmp slt i32 %a, %b + br i1 %wb, label %t1, label %t2 +t1: + %t1v = add i32 %a, 4 + br label %exit +t2: + %t2v = add i32 %b, 8 + br label %exit +exit: + %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] + ret i32 %v +} + +; CHECK-LABEL: brcc_uge: +; CHECK: bltu a2, a3, .LBB8_2 +; CHECK: addi a2, a2, 4 +; CHECK: .LBB8_2: +define i32 @brcc_uge(i32 %a, i32 %b) nounwind { +entry: + %wb = icmp uge i32 %a, %b + br i1 %wb, label %t1, label %t2 +t1: + %t1v = add i32 %a, 4 + br label %exit +t2: + %t2v = add i32 %b, 8 + br label %exit +exit: + %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] + ret i32 %v +} + +; CHECK-LABEL: brcc_ult: +; CHECK: bgeu a2, a3, .LBB9_2 +; CHECK: addi a2, a2, 4 +; CHECK: .LBB9_2: +define i32 @brcc_ult(i32 %a, i32 %b) nounwind { +entry: + %wb = icmp ult i32 %a, %b + br i1 %wb, label %t1, label %t2 +t1: + %t1v = add i32 %a, 4 + br label %exit +t2: + %t2v = add i32 %b, 8 + br label %exit +exit: + %v = phi i32 [ %t1v, %t1 ], [ %t2v, %t2 ] + ret i32 %v +} From ac634c8b08adef1da8114821fbb7ad8a70e994a2 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Tue, 9 Jul 2024 14:50:34 +0300 Subject: [PATCH 4/7] [Xtensa] Add tests for SELECTCC/SETCC with i64 operands. Implemented new tests for SELECTCC/SETCC with i64 operands. Added minor code fixes. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 98 ++-- llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 2 +- llvm/test/CodeGen/Xtensa/select-cc.ll | 346 +++++++++++- llvm/test/CodeGen/Xtensa/setcc.ll | 514 +++++++++++++++++- 4 files changed, 877 insertions(+), 83 deletions(-) diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 901ec133d59229..8bf1e126142965 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -517,6 +517,38 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps); } +static unsigned getBranchOpcode(ISD::CondCode Cond, bool &BrInv) { + BrInv = false; + switch (Cond) { + case ISD::SETEQ: + return Xtensa::BEQ; + case ISD::SETNE: + return Xtensa::BNE; + case ISD::SETLT: + return Xtensa::BLT; + case ISD::SETLE: + BrInv = true; + return Xtensa::BGE; + case ISD::SETGT: + BrInv = true; + return Xtensa::BLT; + case ISD::SETGE: + return Xtensa::BGE; + case ISD::SETULT: + return Xtensa::BLTU; + case ISD::SETULE: + BrInv = true; + return Xtensa::BGEU; + case ISD::SETUGT: + BrInv = true; + return Xtensa::BLTU; + case ISD::SETUGE: + return Xtensa::BGEU; + default: + llvm_unreachable("Unknown branch kind"); + } +} + SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); @@ -526,11 +558,19 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, SDValue TrueValue = Op.getOperand(2); SDValue FalseValue = Op.getOperand(3); ISD::CondCode CC = cast(Op->getOperand(4))->get(); - SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32); + + bool BrInv; + unsigned BrKind = getBranchOpcode(CC, BrInv); + SDValue TargetCC = DAG.getConstant(BrKind, DL, MVT::i32); // Wrap select nodes - return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, - FalseValue, TargetCC); + if (BrInv) { + return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, RHS, LHS, TrueValue, + FalseValue, TargetCC); + } else { + return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, + FalseValue, TargetCC); + } } SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, @@ -728,37 +768,6 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const { // Custom insertion //===----------------------------------------------------------------------===// -static int GetBranchKind(int Cond, bool &BrInv) { - switch (Cond) { - case ISD::SETEQ: - return Xtensa::BEQ; - case ISD::SETNE: - return Xtensa::BNE; - case ISD::SETLT: - return Xtensa::BLT; - case ISD::SETLE: - BrInv = true; - return Xtensa::BGE; - case ISD::SETGT: - BrInv = true; - return Xtensa::BLT; - case ISD::SETGE: - return Xtensa::BGE; - case ISD::SETULT: - return Xtensa::BLTU; - case ISD::SETULE: - BrInv = true; - return Xtensa::BGEU; - case ISD::SETUGT: - BrInv = true; - return Xtensa::BLTU; - case ISD::SETUGE: - return Xtensa::BGEU; - default: - return -1; - } -} - MachineBasicBlock * XtensaTargetLowering::emitSelectCC(MachineInstr &MI, MachineBasicBlock *MBB) const { @@ -769,7 +778,7 @@ XtensaTargetLowering::emitSelectCC(MachineInstr &MI, MachineOperand &RHS = MI.getOperand(2); MachineOperand &TrueValue = MI.getOperand(3); MachineOperand &FalseValue = MI.getOperand(4); - MachineOperand &Cond = MI.getOperand(5); + unsigned BrKind = MI.getOperand(5).getImm(); // To "insert" a SELECT_CC instruction, we actually have to insert // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi @@ -801,19 +810,10 @@ XtensaTargetLowering::emitSelectCC(MachineInstr &MI, MBB->addSuccessor(CopyMBB); MBB->addSuccessor(SinkMBB); - bool BrInv = false; - int BrKind = GetBranchKind(Cond.getImm(), BrInv); - if (BrInv) { - BuildMI(MBB, DL, TII.get(BrKind)) - .addReg(RHS.getReg()) - .addReg(LHS.getReg()) - .addMBB(SinkMBB); - } else { - BuildMI(MBB, DL, TII.get(BrKind)) - .addReg(LHS.getReg()) - .addReg(RHS.getReg()) - .addMBB(SinkMBB); - } + BuildMI(MBB, DL, TII.get(BrKind)) + .addReg(LHS.getReg()) + .addReg(RHS.getReg()) + .addMBB(SinkMBB); CopyMBB->addSuccessor(SinkMBB); @@ -838,6 +838,6 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter( case Xtensa::SELECT: return emitSelectCC(MI, MBB); default: - report_fatal_error("Unexpected instr type to insert"); + llvm_unreachable("Unexpected instr type to insert"); } } diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td index 2d8242ad2b5f2b..704f30ceba75ff 100644 --- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td +++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -582,5 +582,5 @@ let Defs = [SP], Uses = [SP] in { let usesCustomInserter = 1 in { def SELECT : Pseudo<(outs AR:$dst), (ins AR:$lhs, AR:$rhs, AR:$t, AR:$f, i32imm:$cond), "!select $dst, $lhs, $rhs, $t, $f, $cond", - [(set AR:$dst, (Xtensa_select_cc AR:$lhs, AR:$rhs, AR:$t, AR:$f, imm:$cond))]>; + [(set i32:$dst, (Xtensa_select_cc i32:$lhs, i32:$rhs, i32:$t, i32:$f, imm:$cond))]>; } diff --git a/llvm/test/CodeGen/Xtensa/select-cc.ll b/llvm/test/CodeGen/Xtensa/select-cc.ll index 3a020ec4332333..82a7df9934653c 100644 --- a/llvm/test/CodeGen/Xtensa/select-cc.ll +++ b/llvm/test/CodeGen/Xtensa/select-cc.ll @@ -1,7 +1,7 @@ ; RUN: llc -mtriple=xtensa -disable-block-placement -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -define signext i32 @f_eq(i32 signext %a, ptr %b) nounwind { +define i32 @f_eq(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_eq: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: beq a2, a8, .LBB0_2 @@ -15,7 +15,7 @@ define signext i32 @f_eq(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_ne(i32 signext %a, ptr %b) nounwind { +define i32 @f_ne(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ne: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bne a2, a8, .LBB1_2 @@ -29,7 +29,7 @@ define signext i32 @f_ne(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_ugt(i32 signext %a, ptr %b) nounwind { +define i32 @f_ugt(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ugt: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bltu a8, a2, .LBB2_2 @@ -43,7 +43,7 @@ define signext i32 @f_ugt(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_uge(i32 signext %a, ptr %b) nounwind { +define i32 @f_uge(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_uge: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bgeu a2, a8, .LBB3_2 @@ -57,7 +57,7 @@ define signext i32 @f_uge(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_ult(i32 signext %a, ptr %b) nounwind { +define i32 @f_ult(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ult: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bltu a2, a8, .LBB4_2 @@ -71,7 +71,7 @@ define signext i32 @f_ult(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_ule(i32 signext %a, ptr %b) nounwind { +define i32 @f_ule(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ule: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bgeu a8, a2, .LBB5_2 @@ -85,7 +85,7 @@ define signext i32 @f_ule(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_sgt(i32 signext %a, ptr %b) nounwind { +define i32 @f_sgt(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sgt: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: blt a8, a2, .LBB6_2 @@ -99,7 +99,7 @@ define signext i32 @f_sgt(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_sge(i32 signext %a, ptr %b) nounwind { +define i32 @f_sge(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sge: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bge a2, a8, .LBB7_2 @@ -113,7 +113,7 @@ define signext i32 @f_sge(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_slt(i32 signext %a, ptr %b) nounwind { +define i32 @f_slt(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_slt: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: blt a2, a8, .LBB8_2 @@ -127,7 +127,7 @@ define signext i32 @f_slt(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_sle(i32 signext %a, ptr %b) nounwind { +define i32 @f_sle(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sle: ; CHECK: l32i a8, a3, 0 ; CHECK-NEXT: bge a8, a2, .LBB9_2 @@ -141,7 +141,7 @@ define signext i32 @f_sle(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_slt_imm(i32 signext %a, ptr %b) nounwind { +define i32 @f_slt_imm(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_slt_imm: ; CHECK: movi a8, 1 ; CHECK-NEXT: blt a2, a8, .LBB10_2 @@ -155,7 +155,7 @@ define signext i32 @f_slt_imm(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_sgt_imm(i32 signext %a, ptr %b) nounwind { +define i32 @f_sgt_imm(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sgt_imm: ; CHECK: movi a8, -1 ; CHECK-NEXT: blt a8, a2, .LBB11_2 @@ -169,7 +169,7 @@ define signext i32 @f_sgt_imm(i32 signext %a, ptr %b) nounwind { ret i32 %val2 } -define signext i32 @f_ult_imm(i32 signext %a, ptr %b) nounwind { +define i32 @f_ult_imm(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ult_imm: ; CHECK: movi a8, 1024 ; CHECK-NEXT: bltu a2, a8, .LBB12_2 @@ -182,3 +182,323 @@ define signext i32 @f_ult_imm(i32 signext %a, ptr %b) nounwind { %val2 = select i1 %tst1, i32 %a, i32 %val1 ret i32 %val2 } + +; Tests for i64 operands + +define i64 @f_eq_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_eq_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: xor a9, a3, a8 +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: xor a10, a2, a11 +; CHECK-NEXT: or a9, a10, a9 +; CHECK-NEXT: movi a10, 0 +; CHECK-NEXT: beq a9, a10, .LBB13_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB13_2: +; CHECK-NEXT: beq a9, a10, .LBB13_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB13_4: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp eq i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_ne_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_ne_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: xor a9, a3, a8 +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: xor a10, a2, a11 +; CHECK-NEXT: or a9, a10, a9 +; CHECK-NEXT: movi a10, 0 +; CHECK-NEXT: bne a9, a10, .LBB14_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB14_2: +; CHECK-NEXT: bne a9, a10, .LBB14_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB14_4: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp ne i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_ugt_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_ugt_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: bltu a8, a3, .LBB15_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB15_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bltu a11, a2, .LBB15_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB15_4: +; CHECK-NEXT: beq a3, a8, .LBB15_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB15_6: +; CHECK-NEXT: bne a10, a9, .LBB15_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB15_8: +; CHECK-NEXT: bne a10, a9, .LBB15_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB15_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp ugt i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_uge_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_uge_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: bgeu a3, a8, .LBB16_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB16_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bgeu a2, a11, .LBB16_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB16_4: +; CHECK-NEXT: beq a3, a8, .LBB16_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB16_6: +; CHECK-NEXT: bne a10, a9, .LBB16_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB16_8: +; CHECK-NEXT: bne a10, a9, .LBB16_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB16_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp uge i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_ult_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_ult_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: bltu a3, a8, .LBB17_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB17_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bltu a2, a11, .LBB17_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB17_4: +; CHECK-NEXT: beq a3, a8, .LBB17_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB17_6: +; CHECK-NEXT: bne a10, a9, .LBB17_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB17_8: +; CHECK-NEXT: bne a10, a9, .LBB17_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB17_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp ult i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_ule_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_ule_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: bgeu a8, a3, .LBB18_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB18_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bgeu a11, a2, .LBB18_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB18_4: +; CHECK-NEXT: beq a3, a8, .LBB18_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB18_6: +; CHECK-NEXT: bne a10, a9, .LBB18_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB18_8: +; CHECK-NEXT: bne a10, a9, .LBB18_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB18_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp ule i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_sgt_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_sgt_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: blt a8, a3, .LBB19_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB19_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bltu a11, a2, .LBB19_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB19_4: +; CHECK-NEXT: beq a3, a8, .LBB19_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB19_6: +; CHECK-NEXT: bne a10, a9, .LBB19_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB19_8: +; CHECK-NEXT: bne a10, a9, .LBB19_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB19_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp sgt i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_sge_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_sge_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: bge a3, a8, .LBB20_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB20_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bgeu a2, a11, .LBB20_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB20_4: +; CHECK-NEXT: beq a3, a8, .LBB20_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB20_6: +; CHECK-NEXT: bne a10, a9, .LBB20_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB20_8: +; CHECK-NEXT: bne a10, a9, .LBB20_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB20_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp sge i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_slt_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_slt_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: blt a3, a8, .LBB21_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB21_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bltu a2, a11, .LBB21_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB21_4: +; CHECK-NEXT: beq a3, a8, .LBB21_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB21_6: +; CHECK-NEXT: bne a10, a9, .LBB21_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB21_8: +; CHECK-NEXT: bne a10, a9, .LBB21_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB21_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp slt i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} + +define i64 @f_sle_i64(i64 %a, ptr %b) nounwind { +; CHECK-LABEL: f_sle_i64: +; CHECK: l32i a8, a4, 4 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: or a7, a10, a10 +; CHECK-NEXT: bge a8, a3, .LBB22_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a7, a9, a9 +; CHECK-NEXT: .LBB22_2: +; CHECK-NEXT: l32i a11, a4, 0 +; CHECK-NEXT: bgeu a11, a2, .LBB22_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: or a10, a9, a9 +; CHECK-NEXT: .LBB22_4: +; CHECK-NEXT: beq a3, a8, .LBB22_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: or a10, a7, a7 +; CHECK-NEXT: .LBB22_6: +; CHECK-NEXT: bne a10, a9, .LBB22_8 +; CHECK-NEXT: # %bb.7: +; CHECK-NEXT: or a2, a11, a11 +; CHECK-NEXT: .LBB22_8: +; CHECK-NEXT: bne a10, a9, .LBB22_10 +; CHECK-NEXT: # %bb.9: +; CHECK-NEXT: or a3, a8, a8 +; CHECK-NEXT: .LBB22_10: +; CHECK-NEXT: ret + %val1 = load i64, ptr %b + %tst1 = icmp sle i64 %a, %val1 + %val2 = select i1 %tst1, i64 %a, i64 %val1 + ret i64 %val2 +} diff --git a/llvm/test/CodeGen/Xtensa/setcc.ll b/llvm/test/CodeGen/Xtensa/setcc.ll index f3dccf0d1bdcc2..50382356c50e5c 100644 --- a/llvm/test/CodeGen/Xtensa/setcc.ll +++ b/llvm/test/CodeGen/Xtensa/setcc.ll @@ -1,7 +1,8 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -mtriple=xtensa-unkonwn-elf -O0 | FileCheck %s -define i32 @f1(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f1: +define i32 @f_eq(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_eq: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -23,8 +24,8 @@ define i32 @f1(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f2(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f2: +define i32 @f_slt(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_slt: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -46,8 +47,8 @@ define i32 @f2(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f3(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f3: +define i32 @f_sle(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_sle: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -69,8 +70,8 @@ define i32 @f3(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f4(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f4: +define i32 @f_sgt(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_sgt: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -92,8 +93,8 @@ define i32 @f4(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f5(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f5: +define i32 @f_sge(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_sge: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -115,8 +116,8 @@ define i32 @f5(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f6(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f6: +define i32 @f_ne(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_ne: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -138,8 +139,8 @@ define i32 @f6(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f7(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f7: +define i32 @f_ult(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_ult: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -161,8 +162,8 @@ define i32 @f7(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f8(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f8: +define i32 @f_ule(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_ule: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -184,8 +185,8 @@ define i32 @f8(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f9(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f9: +define i32 @f_ugt(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_ugt: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -207,8 +208,8 @@ define i32 @f9(i32 %a, i32 %b) nounwind { ret i32 %res } -define i32 @f10(i32 %a, i32 %b) nounwind { -; CHECK-LABEL: f10: +define i32 @f_uge(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: f_uge: ; CHECK: addi a8, a1, -16 ; CHECK-NEXT: or a1, a8, a8 ; CHECK-NEXT: movi a8, 0 @@ -229,3 +230,476 @@ define i32 @f10(i32 %a, i32 %b) nounwind { %res = zext i1 %cond to i32 ret i32 %res } + + +; Tests for i64 operands + +define i64 @f_eq_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_eq_i64: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a4 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: # kill: def $a8 killed $a2 +; CHECK-NEXT: xor a9, a3, a5 +; CHECK-NEXT: xor a8, a2, a4 +; CHECK-NEXT: or a8, a8, a9 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: s32i a9, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB10_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB10_2: +; CHECK-NEXT: l32i a3, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp eq i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_slt_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_slt_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: blt a3, a5, .LBB11_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB11_2: +; CHECK-NEXT: l32i a8, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bltu a8, a9, .LBB11_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB11_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB11_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB11_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp slt i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_sle_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_sle_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: bge a5, a3, .LBB12_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB12_2: +; CHECK-NEXT: l32i a8, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a8, a9, .LBB12_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB12_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB12_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB12_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp sle i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_sgt_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_sgt_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: blt a5, a3, .LBB13_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB13_2: +; CHECK-NEXT: l32i a8, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bltu a8, a9, .LBB13_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB13_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB13_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB13_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp sgt i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_sge_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_sge_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: bge a3, a5, .LBB14_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB14_2: +; CHECK-NEXT: l32i a8, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a8, a9, .LBB14_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB14_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB14_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB14_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp sge i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_ne_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_ne_i64: +; CHECK: addi a8, a1, -16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a4 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: # kill: def $a8 killed $a2 +; CHECK-NEXT: xor a9, a3, a5 +; CHECK-NEXT: xor a8, a2, a4 +; CHECK-NEXT: or a8, a8, a9 +; CHECK-NEXT: movi a10, 1 +; CHECK-NEXT: movi a9, 0 +; CHECK-NEXT: s32i a9, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: bne a8, a9, .LBB15_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: .LBB15_2: +; CHECK-NEXT: l32i a3, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 16 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ne i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_ult_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_ult_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: bltu a3, a5, .LBB16_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB16_2: +; CHECK-NEXT: l32i a8, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bltu a8, a9, .LBB16_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB16_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB16_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB16_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ult i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_ule_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_ule_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a5, a3, .LBB17_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB17_2: +; CHECK-NEXT: l32i a8, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a8, a9, .LBB17_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB17_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB17_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB17_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ule i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_ugt_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_ugt_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: bltu a5, a3, .LBB18_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB18_2: +; CHECK-NEXT: l32i a8, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bltu a8, a9, .LBB18_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB18_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB18_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB18_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp ugt i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} + +define i64 @f_uge_i64(i64 %a, i64 %b) nounwind { +; CHECK-LABEL: f_uge_i64: +; CHECK: addi a8, a1, -48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: s32i a5, a1, 12 # 4-byte Folded Spill +; CHECK-NEXT: s32i a4, a1, 16 # 4-byte Folded Spill +; CHECK-NEXT: s32i a3, a1, 20 # 4-byte Folded Spill +; CHECK-NEXT: s32i a2, a1, 24 # 4-byte Folded Spill +; CHECK-NEXT: # kill: def $a8 killed $a5 +; CHECK-NEXT: # kill: def $a8 killed $a3 +; CHECK-NEXT: movi a8, 0 +; CHECK-NEXT: s32i a8, a1, 28 # 4-byte Folded Spill +; CHECK-NEXT: movi a8, 1 +; CHECK-NEXT: s32i a8, a1, 32 # 4-byte Folded Spill +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a3, a5, .LBB19_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 36 # 4-byte Folded Spill +; CHECK-NEXT: .LBB19_2: +; CHECK-NEXT: l32i a8, a1, 24 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 16 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 32 # 4-byte Folded Reload +; CHECK-NEXT: l32i a11, a1, 36 # 4-byte Folded Reload +; CHECK-NEXT: s32i a11, a1, 4 # 4-byte Folded Spill +; CHECK-NEXT: s32i a10, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: bgeu a8, a9, .LBB19_4 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: l32i a8, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 8 # 4-byte Folded Spill +; CHECK-NEXT: .LBB19_4: +; CHECK-NEXT: l32i a8, a1, 20 # 4-byte Folded Reload +; CHECK-NEXT: l32i a9, a1, 12 # 4-byte Folded Reload +; CHECK-NEXT: l32i a10, a1, 8 # 4-byte Folded Reload +; CHECK-NEXT: s32i a10, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: beq a8, a9, .LBB19_6 +; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: l32i a8, a1, 4 # 4-byte Folded Reload +; CHECK-NEXT: s32i a8, a1, 0 # 4-byte Folded Spill +; CHECK-NEXT: .LBB19_6: +; CHECK-NEXT: l32i a3, a1, 28 # 4-byte Folded Reload +; CHECK-NEXT: l32i a2, a1, 0 # 4-byte Folded Reload +; CHECK-NEXT: addi a8, a1, 48 +; CHECK-NEXT: or a1, a8, a8 +; CHECK-NEXT: ret + + %cond = icmp uge i64 %a, %b + %res = zext i1 %cond to i64 + ret i64 %res +} From f32928f33146a3a833337bbac278256b45a51e11 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Wed, 10 Jul 2024 11:57:04 +0300 Subject: [PATCH 5/7] [Xtensa] Minor fixes in code. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 8bf1e126142965..2c5991c724b3f4 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -564,13 +564,8 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, SDValue TargetCC = DAG.getConstant(BrKind, DL, MVT::i32); // Wrap select nodes - if (BrInv) { - return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, RHS, LHS, TrueValue, - FalseValue, TargetCC); - } else { - return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, - FalseValue, TargetCC); - } + return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, BrInv ? RHS : LHS, + BrInv ? LHS : RHS, TrueValue, FalseValue, TargetCC); } SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, From e6a00f47937be6bc6df167b4b2dcdafee7dbd34b Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Wed, 10 Jul 2024 15:44:44 +0300 Subject: [PATCH 6/7] [Xtensa] Expand actions for GT/UGT/LE/ULE code condtions. The GT/UGT/LE/ULE code condtions not supported for i32, some expand actions for these codes. Also corrected brcc.ll/select-cc.ll/setcc.ll tests. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 19 ++- llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 10 -- llvm/test/CodeGen/Xtensa/brcc.ll | 153 ++++++++++++------ llvm/test/CodeGen/Xtensa/select-cc.ll | 28 ++-- llvm/test/CodeGen/Xtensa/setcc.ll | 3 +- 5 files changed, 129 insertions(+), 84 deletions(-) diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 2c5991c724b3f4..44c9856c05d131 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -93,6 +93,11 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); setOperationAction(ISD::SETCC, MVT::i32, Expand); + setCondCodeAction(ISD::SETGT, MVT::i32, Expand); + setCondCodeAction(ISD::SETLE, MVT::i32, Expand); + setCondCodeAction(ISD::SETUGT, MVT::i32, Expand); + setCondCodeAction(ISD::SETULE, MVT::i32, Expand); + // Implement custom stack allocations setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); // Implement custom stack save and restore @@ -517,8 +522,7 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps); } -static unsigned getBranchOpcode(ISD::CondCode Cond, bool &BrInv) { - BrInv = false; +static unsigned getBranchOpcode(ISD::CondCode Cond) { switch (Cond) { case ISD::SETEQ: return Xtensa::BEQ; @@ -527,20 +531,16 @@ static unsigned getBranchOpcode(ISD::CondCode Cond, bool &BrInv) { case ISD::SETLT: return Xtensa::BLT; case ISD::SETLE: - BrInv = true; return Xtensa::BGE; case ISD::SETGT: - BrInv = true; return Xtensa::BLT; case ISD::SETGE: return Xtensa::BGE; case ISD::SETULT: return Xtensa::BLTU; case ISD::SETULE: - BrInv = true; return Xtensa::BGEU; case ISD::SETUGT: - BrInv = true; return Xtensa::BLTU; case ISD::SETUGE: return Xtensa::BGEU; @@ -559,13 +559,12 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, SDValue FalseValue = Op.getOperand(3); ISD::CondCode CC = cast(Op->getOperand(4))->get(); - bool BrInv; - unsigned BrKind = getBranchOpcode(CC, BrInv); + unsigned BrKind = getBranchOpcode(CC); SDValue TargetCC = DAG.getConstant(BrKind, DL, MVT::i32); // Wrap select nodes - return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, BrInv ? RHS : LHS, - BrInv ? LHS : RHS, TrueValue, FalseValue, TargetCC); + return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, + FalseValue, TargetCC); } SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td index 704f30ceba75ff..fc134e794153b6 100644 --- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td +++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -416,16 +416,6 @@ def BBSI : RRI8_Inst<0x07, (outs), let imm8 = target; } -def : Pat<(brcc SETGT, AR:$s, AR:$t, bb:$target), - (BLT AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcc SETUGT, AR:$s, AR:$t, bb:$target), - (BLTU AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcc SETLE, AR:$s, AR:$t, bb:$target), - (BGE AR:$t, AR:$s, bb:$target)>; -def : Pat<(brcc SETULE, AR:$s, AR:$t, bb:$target), - (BGEU AR:$t, AR:$s, bb:$target)>; - - //===----------------------------------------------------------------------===// // Call and jump instructions //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/Xtensa/brcc.ll b/llvm/test/CodeGen/Xtensa/brcc.ll index 05e59d36993eda..8bbc39c536c561 100644 --- a/llvm/test/CodeGen/Xtensa/brcc.ll +++ b/llvm/test/CodeGen/Xtensa/brcc.ll @@ -1,11 +1,17 @@ -; RUN: llc -march=xtensa < %s | FileCheck %s +; RUN: llc -mtriple=xtensa -disable-block-placement -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -; CHECK-LABEL: brcc_sgt: -; CHECK: bge a3, a2, .LBB0_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB0_2: define i32 @brcc_sgt(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_sgt: +; CHECK: bge a3, a2, .LBB0_2 +; CHECK-NEXT: j .LBB0_1 +; CHECK-NEXT: .LBB0_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB0_3 +; CHECK-NEXT: .LBB0_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB0_3: # %exit +; CHECK-NEXT: ret %wb = icmp sgt i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -19,12 +25,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_ugt -; CHECK: bgeu a3, a2, .LBB1_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB1_2: define i32 @brcc_ugt(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_ugt: +; CHECK: bgeu a3, a2, .LBB1_2 +; CHECK-NEXT: j .LBB1_1 +; CHECK-NEXT: .LBB1_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB1_3 +; CHECK-NEXT: .LBB1_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB1_3: # %exit +; CHECK-NEXT: ret %wb = icmp ugt i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -38,12 +49,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_sle: -; CHECK: blt a3, a2, .LBB2_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB2_2: define i32 @brcc_sle(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_sle: +; CHECK: blt a3, a2, .LBB2_2 +; CHECK-NEXT: j .LBB2_1 +; CHECK-NEXT: .LBB2_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB2_3 +; CHECK-NEXT: .LBB2_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB2_3: # %exit +; CHECK-NEXT: ret %wb = icmp sle i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -57,12 +73,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_ule -; CHECK: bltu a3, a2, .LBB3_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB3_2: define i32 @brcc_ule(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_ule: +; CHECK: bltu a3, a2, .LBB3_2 +; CHECK-NEXT: j .LBB3_1 +; CHECK-NEXT: .LBB3_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB3_3 +; CHECK-NEXT: .LBB3_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB3_3: # %exit +; CHECK-NEXT: ret %wb = icmp ule i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -76,12 +97,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_eq: -; CHECK: bne a2, a3, .LBB4_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB4_2: define i32 @brcc_eq(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_eq: +; CHECK: bne a2, a3, .LBB4_2 +; CHECK-NEXT: j .LBB4_1 +; CHECK-NEXT: .LBB4_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB4_3 +; CHECK-NEXT: .LBB4_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB4_3: # %exit +; CHECK-NEXT: ret %wb = icmp eq i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -95,12 +121,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_ne: -; CHECK: beq a2, a3, .LBB5_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB5_2: define i32 @brcc_ne(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_ne: +; CHECK: beq a2, a3, .LBB5_2 +; CHECK-NEXT: j .LBB5_1 +; CHECK-NEXT: .LBB5_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB5_3 +; CHECK-NEXT: .LBB5_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB5_3: # %exit +; CHECK-NEXT: ret %wb = icmp ne i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -114,12 +145,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_ge: -; CHECK: blt a2, a3, .LBB6_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB6_2: define i32 @brcc_ge(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_ge: +; CHECK: blt a2, a3, .LBB6_2 +; CHECK-NEXT: j .LBB6_1 +; CHECK-NEXT: .LBB6_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB6_3 +; CHECK-NEXT: .LBB6_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB6_3: # %exit +; CHECK-NEXT: ret %wb = icmp sge i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -133,12 +169,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_lt: -; CHECK: bge a2, a3, .LBB7_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB7_2: define i32 @brcc_lt(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_lt: +; CHECK: bge a2, a3, .LBB7_2 +; CHECK-NEXT: j .LBB7_1 +; CHECK-NEXT: .LBB7_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB7_3 +; CHECK-NEXT: .LBB7_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB7_3: # %exit +; CHECK-NEXT: ret %wb = icmp slt i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -152,12 +193,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_uge: -; CHECK: bltu a2, a3, .LBB8_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB8_2: define i32 @brcc_uge(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_uge: +; CHECK: bltu a2, a3, .LBB8_2 +; CHECK-NEXT: j .LBB8_1 +; CHECK-NEXT: .LBB8_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB8_3 +; CHECK-NEXT: .LBB8_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB8_3: # %exit +; CHECK-NEXT: ret %wb = icmp uge i32 %a, %b br i1 %wb, label %t1, label %t2 t1: @@ -171,12 +217,17 @@ exit: ret i32 %v } -; CHECK-LABEL: brcc_ult: -; CHECK: bgeu a2, a3, .LBB9_2 -; CHECK: addi a2, a2, 4 -; CHECK: .LBB9_2: define i32 @brcc_ult(i32 %a, i32 %b) nounwind { -entry: +; CHECK-LABEL: brcc_ult: +; CHECK: bgeu a2, a3, .LBB9_2 +; CHECK-NEXT: j .LBB9_1 +; CHECK-NEXT: .LBB9_1: # %t1 +; CHECK-NEXT: addi a2, a2, 4 +; CHECK-NEXT: j .LBB9_3 +; CHECK-NEXT: .LBB9_2: # %t2 +; CHECK-NEXT: addi a2, a3, 8 +; CHECK-NEXT: .LBB9_3: # %exit +; CHECK-NEXT: ret %wb = icmp ult i32 %a, %b br i1 %wb, label %t1, label %t2 t1: diff --git a/llvm/test/CodeGen/Xtensa/select-cc.ll b/llvm/test/CodeGen/Xtensa/select-cc.ll index 82a7df9934653c..812e6a5b852eab 100644 --- a/llvm/test/CodeGen/Xtensa/select-cc.ll +++ b/llvm/test/CodeGen/Xtensa/select-cc.ll @@ -31,8 +31,9 @@ define i32 @f_ne(i32 %a, ptr %b) nounwind { define i32 @f_ugt(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ugt: -; CHECK: l32i a8, a3, 0 -; CHECK-NEXT: bltu a8, a2, .LBB2_2 +; CHECK: or a8, a2, a2 +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: bgeu a2, a8, .LBB2_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: or a2, a8, a8 ; CHECK-NEXT: .LBB2_2: @@ -73,8 +74,9 @@ define i32 @f_ult(i32 %a, ptr %b) nounwind { define i32 @f_ule(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_ule: -; CHECK: l32i a8, a3, 0 -; CHECK-NEXT: bgeu a8, a2, .LBB5_2 +; CHECK: or a8, a2, a2 +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: bltu a2, a8, .LBB5_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: or a2, a8, a8 ; CHECK-NEXT: .LBB5_2: @@ -87,8 +89,9 @@ define i32 @f_ule(i32 %a, ptr %b) nounwind { define i32 @f_sgt(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sgt: -; CHECK: l32i a8, a3, 0 -; CHECK-NEXT: blt a8, a2, .LBB6_2 +; CHECK: or a8, a2, a2 +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: bge a2, a8, .LBB6_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: or a2, a8, a8 ; CHECK-NEXT: .LBB6_2: @@ -129,8 +132,9 @@ define i32 @f_slt(i32 %a, ptr %b) nounwind { define i32 @f_sle(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sle: -; CHECK: l32i a8, a3, 0 -; CHECK-NEXT: bge a8, a2, .LBB9_2 +; CHECK: or a8, a2, a2 +; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: blt a2, a8, .LBB9_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: or a2, a8, a8 ; CHECK-NEXT: .LBB9_2: @@ -157,10 +161,12 @@ define i32 @f_slt_imm(i32 %a, ptr %b) nounwind { define i32 @f_sgt_imm(i32 %a, ptr %b) nounwind { ; CHECK-LABEL: f_sgt_imm: -; CHECK: movi a8, -1 -; CHECK-NEXT: blt a8, a2, .LBB11_2 -; CHECK-NEXT: # %bb.1: +; CHECK: or a8, a2, a2 ; CHECK-NEXT: l32i a2, a3, 0 +; CHECK-NEXT: movi a9, -1 +; CHECK-NEXT: bge a9, a8, .LBB11_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: or a2, a8, a8 ; CHECK-NEXT: .LBB11_2: ; CHECK-NEXT: ret %val1 = load i32, ptr %b diff --git a/llvm/test/CodeGen/Xtensa/setcc.ll b/llvm/test/CodeGen/Xtensa/setcc.ll index 50382356c50e5c..05eb80e041fbe5 100644 --- a/llvm/test/CodeGen/Xtensa/setcc.ll +++ b/llvm/test/CodeGen/Xtensa/setcc.ll @@ -1,5 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 -; RUN: llc < %s -mtriple=xtensa-unkonwn-elf -O0 | FileCheck %s +; RUN: llc < %s -mtriple=xtensa -O0 | FileCheck %s define i32 @f_eq(i32 %a, i32 %b) nounwind { ; CHECK-LABEL: f_eq: From 08b5ec10de1411f98508fcc9fcd039073f2ad3a5 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Thu, 11 Jul 2024 02:57:18 +0300 Subject: [PATCH 7/7] [Xtensa] Minor fixes. Renamed variable and removed redundant comments. --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 5 ++--- llvm/lib/Target/Xtensa/XtensaISelLowering.h | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 44c9856c05d131..5d5a34157cc9f6 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -559,10 +559,9 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op, SDValue FalseValue = Op.getOperand(3); ISD::CondCode CC = cast(Op->getOperand(4))->get(); - unsigned BrKind = getBranchOpcode(CC); - SDValue TargetCC = DAG.getConstant(BrKind, DL, MVT::i32); + unsigned BrOpcode = getBranchOpcode(CC); + SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32); - // Wrap select nodes return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue, FalseValue, TargetCC); } diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h index 657756dc30950e..dd811ae9f3a774 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -39,7 +39,7 @@ enum { // a false value (ops #2 and #3) based on the boolean result of comparing // the lhs and rhs (ops #0 and #1) of a conditional expression with the // condition code in op #4 - SELECT_CC + SELECT_CC, }; } @@ -115,7 +115,6 @@ class XtensaTargetLowering : public TargetLowering { CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; - // Implement EmitInstrWithCustomInserter for individual operation types. MachineBasicBlock *emitSelectCC(MachineInstr &MI, MachineBasicBlock *BB) const; };