Index: lib/Target/PowerPC/CMakeLists.txt =================================================================== --- lib/Target/PowerPC/CMakeLists.txt +++ lib/Target/PowerPC/CMakeLists.txt @@ -40,6 +40,7 @@ PPCVSXCopy.cpp PPCVSXFMAMutate.cpp PPCVSXSwapRemoval.cpp + PPCExpandISEL.cpp ) add_subdirectory(AsmParser) Index: lib/Target/PowerPC/PPC.h =================================================================== --- lib/Target/PowerPC/PPC.h +++ lib/Target/PowerPC/PPC.h @@ -45,6 +45,7 @@ FunctionPass *createPPCISelDag(PPCTargetMachine &TM); FunctionPass *createPPCTLSDynamicCallPass(); FunctionPass *createPPCBoolRetToIntPass(); + FunctionPass *createPPCExpandISELPass(); void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP, bool isDarwin); Index: lib/Target/PowerPC/PPCExpandISEL.cpp =================================================================== --- /dev/null +++ lib/Target/PowerPC/PPCExpandISEL.cpp @@ -0,0 +1,369 @@ +//===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A pass that expands the ISEL instruction into an if-then-else sequence +// +//===----------------------------------------------------------------------===// + +#include "PPC.h" +#include "PPCInstrInfo.h" +#include "PPCSubtarget.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "ppc-expand-isel" + +STATISTIC(NumExpanded, "Number of ISEL instructions expanded"); +STATISTIC(NumRemoved, "Number of ISEL instructions removed"); +STATISTIC(NumFolded, "Number of ISEL instructions folded"); + +// If ppc-gen-isel=false is set, it will disable generating the ISEL +// instruction on 64-bit non-Darwin PPC targets, for other targets, +// it will still generate the ISEL instructions. +static cl::opt + GenerateISEL("ppc-gen-isel", + cl::desc("Enable generating the ISEL instruction."), + cl::init(true), cl::Hidden); + +namespace llvm { + void initializePPCExpandISELPass(PassRegistry &); +} + +class PPCExpandISEL : public MachineFunctionPass { + + typedef SmallVector BlockISELList; + typedef SmallDenseMap ISELInstructionList; + + // List of ISEL instructions, sorted by MBB. + ISELInstructionList ISELInstructions; + MachineFunction *MF; + + /// + /// \brief Initialize the object + /// + void initialize(MachineFunction & MFParam); + + void expandISELInstruction(MachineInstr & MI); + void expandISELInstructions(); + + /// + /// \brief Is this instruction an ISEL or ISEL8 + /// + bool isISEL(const MachineInstr &MI) const { + return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8); + } + + /// + /// \brief Collect all ISEL instructions from the current function + /// + /// Walk the current function and collect all the ISEL instructions that are + /// found. The instructions are placed in the ISELInstructions vector. + /// + /// \return true if any ISEL instructions were found, false otherwise + /// + bool collectISELInstructions(); + +public: + static char ID; + PPCExpandISEL() : MachineFunctionPass(ID) { + initializePPCExpandISELPass(*PassRegistry::getPassRegistry()); + } + + const TargetInstrInfo *TII; + + /// + /// \brief Determine whether to generate the ISEL instruction or expand it + /// + /// Expand ISEL instructions into if-then-else sequence only when both of + /// the following two conditions hold: + /// (1) 64-bit non-Darwin PPC targets. + /// (2) -ppc-gen-isel=false + /// Otherwise, still generate ISEL instructions. + /// The -ppc-gen-isel option is set to true by default. which means the + /// ISEL insturctions are still generated by default on all platforms. + /// instruction, regardless of the architecture. + /// + /// \return true if ISEL should be expanded into if-then-else code sequence; + /// false if ISEL instruction should be generated, i.e. not expaned. + /// + static bool isExpandISELEnabled(const MachineFunction &MF); + +#ifndef NDEBUG + void DumpISELInstructions() const; +#endif + + bool runOnMachineFunction(MachineFunction & MF) override { + DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n"); + if (!isExpandISELEnabled(MF)) + return false; + + initialize(MF); + + if (!collectISELInstructions()) { + DEBUG(dbgs() << "No ISEL instructions in this function\n"); + return false; + } + +#ifndef NDEBUG + DumpISELInstructions(); +#endif + + expandISELInstructions(); + + return true; + } +}; + +void PPCExpandISEL::initialize(MachineFunction &MFParam) { + MF = &MFParam; + TII = MF->getSubtarget().getInstrInfo(); + ISELInstructions.clear(); +} + +bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) { + if (GenerateISEL) + return false; + + if (MF.getSubtarget().isSVR4ABI() && + MF.getSubtarget().isPPC64()) + return true; + + return false; +} + +bool PPCExpandISEL::collectISELInstructions() { + for (MachineBasicBlock &MBB : *MF) { + BlockISELList thisBlockISELs; + for (MachineInstr &MI : MBB) + if (isISEL(MI)) + thisBlockISELs.push_back(&MI); + if (!thisBlockISELs.empty()) + ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs)); + } + return !ISELInstructions.empty(); +} + +#ifndef NDEBUG +void PPCExpandISEL::DumpISELInstructions() const { + for (ISELInstructionList::const_iterator I = ISELInstructions.begin(), + Iend = ISELInstructions.end(); + I != Iend; ++I) { + DEBUG(dbgs() << "BB#" << I->first << ":\n"); + for (BlockISELList::const_iterator VI = I->second.begin(), + Vend = I->second.end(); + VI != Vend; ++VI) + DEBUG(dbgs() << " "; (*VI)->print(dbgs())); + } +} +#endif + +void PPCExpandISEL::expandISELInstructions() { + for (ISELInstructionList::iterator BlockList = ISELInstructions.begin(), + ListEnd = ISELInstructions.end(); + BlockList != ListEnd; ++BlockList) { + DEBUG(dbgs() << "Expanding ISEL instructions in BB#" << BlockList->first + << "\n"); + BlockISELList &CurrentISELList = BlockList->second; + for (auto I = CurrentISELList.begin(), E = CurrentISELList.end(); I != E; + ++I) { + expandISELInstruction(**I); + } + } +} + + +void PPCExpandISEL::expandISELInstruction(MachineInstr &MI) { + assert(isISEL(MI) && "Expecting an ISEL instruction"); + DEBUG(dbgs() << "MI: " << MI << "\n"); + + MachineOperand &Dest = MI.getOperand(0); // location to store to + MachineOperand &TrueValue = MI.getOperand(1); // Value to store if + // condition is true + MachineOperand &FalseValue = MI.getOperand(2); // Value to store if + // condition is false + MachineOperand &ConditionRegister = MI.getOperand(3); // Condition + + // If the Dest Register and True Value Register are not the same one or they + // are both R0, we need the True Block. + bool IsTrueBlockRequired = ((Dest.getReg() != TrueValue.getReg()) || + (TrueValue.getReg() == 0)); + bool IsFalseBlockRequired = (Dest.getReg() != FalseValue.getReg()); + + // Special case 1, all the registers used by ISEL are the same one but not R0. + // i.e. ISEL Rn Rn Rn (n !=0). In case of ISEL R0,R0,R0,CR The content of R0 + // needs to be set to 0 or not changed depending on unavailable information + // during compile time (the value CR), we will hand this situation in the + // following like normal if-then-else. + if (!IsTrueBlockRequired && !IsFalseBlockRequired) { + DEBUG(dbgs() << "Remove redudant ISEL instruction."); + NumRemoved++; + MI.eraseFromParent(); + return; + } + + DEBUG(dbgs() << "Dest: " << Dest << "\n"); + DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n"); + DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n"); + DEBUG(dbgs() << "ConditionRegister: " << ConditionRegister << "\n"); + + MachineBasicBlock *MBB = MI.getParent(); + DebugLoc dl; + + // Special case 2, the two input registers used by ISEL are the same and + // not R0. + if ((TrueValue.getReg() == FalseValue.getReg()) && + (TrueValue.getReg() != 0)) { + DEBUG(dbgs() << "Fold the ISEL insturction to an unconditonal copy."); + NumFolded++; + BuildMI(*MBB, &MI, dl, TII->get(PPC::ADDI8)) + .addOperand(Dest) + .addOperand(TrueValue) + .addOperand(MachineOperand::CreateImm(0)); + MI.eraseFromParent(); + return; + } + + MachineFunction *Fn = MBB->getParent(); + MachineFunction::iterator It = MBB->getIterator(); + ++It; // Point to the successor block of MBB + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineBasicBlock *TrueBlock = nullptr; + MachineBasicBlock *FalseBlock = nullptr; + MachineBasicBlock::iterator MBBI = MI; + MachineBasicBlock *NewSuccessor = MBBI != MBB->getLastNonDebugInstr() + ? Fn->CreateMachineBasicBlock(LLVM_BB) + : nullptr; + MachineBasicBlock *Successor = nullptr; + + // If NewSuccessor is NULL then the ISEL was the last non-debug instruction + // in this block. Find the fall-through successor of this block to use when + // updating the CFG below + if (!NewSuccessor) { + assert(MBB->canFallThrough() && "This block should fall through!\n"); + for (MachineBasicBlock::succ_iterator SuccIt = MBB->succ_begin(); + SuccIt != MBB->succ_end(); SuccIt++) { + if (MBB->isLayoutSuccessor(*SuccIt)) { + Successor = *SuccIt; + break; + } + } + } else + Successor = NewSuccessor; + + // The FalseBlock and TrueBlock are inserted after the MBB block but before + // its successor conditionally. + // Note this need to be done *after* the above setting the Successor code, + // otherwise the canFallThrough assert will fail. + if (IsFalseBlockRequired) { + FalseBlock = Fn->CreateMachineBasicBlock(LLVM_BB); + Fn->insert(It, FalseBlock); + } + + if (IsTrueBlockRequired) { + TrueBlock = Fn->CreateMachineBasicBlock(LLVM_BB); + Fn->insert(It, TrueBlock); + } + + if (NewSuccessor) { + Fn->insert(It, NewSuccessor); + + // Transfer the rest of this block into the new successor block + NewSuccessor->splice(NewSuccessor->end(), MBB, + std::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB); + + // Copy the liveIn to new successor + for (MachineBasicBlock::livein_iterator LIT = MBB->livein_begin(); + LIT != MBB->livein_end(); LIT++) + NewSuccessor->addLiveIn(*LIT); + } else { + // Remove successor from MBB; + MBB->removeSuccessor(Successor); + } + + // Note that this needs to be done *after* transfering the successors from MBB + // to the NewSuccessor block, otherwise these blocks will also be transferred + // as successors! + MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor); + MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor); + + MachineBasicBlock::iterator TrueBlockI; + MachineBasicBlock::iterator FalseBlockI; + + if (IsTrueBlockRequired) { + TrueBlockI = TrueBlock->begin(); + TrueBlock->addSuccessor(Successor); + } + + if (IsFalseBlockRequired) { + FalseBlockI = FalseBlock->begin(); + FalseBlock->addSuccessor(Successor); + } + + if (IsTrueBlockRequired) { + // Copy the result into the destination if the condition is true + BuildMI(*TrueBlock, TrueBlockI, dl, TII->get(PPC::ADDI8)) + .addOperand(Dest) + .addOperand(TrueValue) + .addOperand(MachineOperand::CreateImm(0)); + + // Add the LiveIn registers required by true block. + TrueBlock->addLiveIn(Dest.getReg()); + TrueBlock->addLiveIn(TrueValue.getReg()); + } + + if (IsFalseBlockRequired) { + // Add the LiveIn registers required by false block. + FalseBlock->addLiveIn(Dest.getReg()); + FalseBlock->addLiveIn(FalseValue.getReg()); + } + + if (NewSuccessor) { + // Add the LiveIn registers required by NewSuccessor block. + NewSuccessor->addLiveIn(Dest.getReg()); + NewSuccessor->addLiveIn(TrueValue.getReg()); + NewSuccessor->addLiveIn(FalseValue.getReg()); + } + + // Conditional branch to the TrueBlock or Successor + BuildMI(*MBB, &MI, dl, TII->get(PPC::BC)) + .addOperand(ConditionRegister) + .addMBB(IsTrueBlockRequired ? TrueBlock : Successor); + + // Copy the value into the destination if the condition is false + if (IsFalseBlockRequired) + BuildMI(*FalseBlock, FalseBlockI, dl, TII->get(PPC::ORI8)) + .addOperand(Dest) + .addOperand(FalseValue) + .addOperand(MachineOperand::CreateImm(0)); + + // Jump over the true block to the new successor if the condition is false + BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB), + (IsFalseBlockRequired ? FalseBlockI : MI), dl, TII->get(PPC::B)) + .addMBB(Successor); + + MI.eraseFromParent(); // remove the ISEL instruction + + NumExpanded++; +} + +INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation", + false, false) + +char PPCExpandISEL::ID = 0; +FunctionPass *llvm::createPPCExpandISELPass() { + return new PPCExpandISEL(); } Index: lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- lib/Target/PowerPC/PPCTargetMachine.cpp +++ lib/Target/PowerPC/PPCTargetMachine.cpp @@ -412,6 +412,8 @@ } void PPCPassConfig::addPreEmitPass() { + addPass(createPPCExpandISELPass(), false); + if (getOptLevel() != CodeGenOpt::None) addPass(createPPCEarlyReturnPass(), false); // Must run branch selection immediately preceding the asm printer. Index: test/CodeGen/PowerPC/crbit-asm.ll =================================================================== --- test/CodeGen/PowerPC/crbit-asm.ll +++ test/CodeGen/PowerPC/crbit-asm.ll @@ -1,5 +1,8 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s ; RUN: llc -verify-machineinstrs -O1 -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck -check-prefix=CHECK-NO-ISEL %s +; RUN: llc -verify-machineinstrs -O1 -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck -check-prefix=CHECK-NO-ISEL %s + target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -18,6 +21,10 @@ ; CHECK-DAG: crand [[REG3:[0-9]+]], [[REG2]], 1 ; CHECK-DAG: li [[REG4:[0-9]+]], 1 ; CHECK: isel 3, [[REG4]], [[REG1]], [[REG3]] +; CHECK-NO-ISEL-LABEL: @testi1 +; CHECK-NO-ISEL: bclr 12, 20, 0 +; CHECK-NO-ISEL: ori 3, 5, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } Index: test/CodeGen/PowerPC/crbits.ll =================================================================== --- test/CodeGen/PowerPC/crbits.ll +++ test/CodeGen/PowerPC/crbits.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -19,6 +20,11 @@ ; CHECK: crnor ; CHECK: crnand [[REG4:[0-9]+]], ; CHECK: isel 3, 0, [[REG1]], [[REG4]] +; CHECK-NO-ISEL-LABEL: @test1 +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 0, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } Index: test/CodeGen/PowerPC/expand-isel.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/expand-isel.ll @@ -0,0 +1,101 @@ +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" +; RUN: llc -verify-machineinstrs -O2 -ppc-asm-full-reg-names -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck %s --implicit-check-not isel +; Function Attrs: norecurse nounwind readnone +define signext i32 @testExpandISELToIfElse(i32 signext %i, i32 signext %j) { +entry: + %cmp = icmp sgt i32 %i, 0 + %add = add nsw i32 %i, 1 + %cond = select i1 %cmp, i32 %add, i32 %j + ret i32 %cond + +; CHECK-LABEL: @testExpandISELToIfElse +; CHECK: addi r5, r3, 1 +; CHECK: cmpwi cr0, r3, 0 +; CHECK: bc 12, 1, .LBB0_2 +; CHECK: ori r3, r4, 0 +; CHECK: b .LBB0_3 +; CHECK: .LBB0_2: +; CHECK: addi r3, r5, 0 +; CHECK: .LBB0_3: +; CHECK: extsw r3, r3 +; CHECK: blr +} + + +; Function Attrs: norecurse nounwind readnone +define signext i32 @testExpandISELToIf(i32 signext %i, i32 signext %j) { +entry: + %cmp = icmp sgt i32 %i, 0 + %cond = select i1 %cmp, i32 %j, i32 %i + ret i32 %cond + +; CHECK-LABEL: @testExpandISELToIf +; CHECK: cmpwi r3, 0 +; CHECK: bc 12, 1, .LBB1_1 +; CHECK: blr +; CHECK: .LBB1_1: +; CHECK: addi r3, r4, 0 +; CHECK: blr +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @testExpandISELToElse(i32 signext %i, i32 signext %j) { +entry: + %cmp = icmp sgt i32 %i, 0 + %cond = select i1 %cmp, i32 %i, i32 %j + ret i32 %cond + +; CHECK-LABEL: @testExpandISELToElse +; CHECK: cmpwi r3, 0 +; CHECK: bclr 12, 1, 0 +; CHECK: ori r3, r4, 0 +; CHECK: blr +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @testExpandISELToNull(i32 signext %i, i32 signext %j) { +entry: + %cmp = icmp sgt i32 %i, 0 + %cond = select i1 %cmp, i32 %i, i32 %i + ret i32 %cond + +; CHECK-LABEL: @testExpandISELToNull +; CHECK-NOT: b .LBB +; CHECK-NOT: bc +; CHECK: blr +} + +@b = common local_unnamed_addr global i32 0, align 4 +@a = common local_unnamed_addr global i32 0, align 4 +; Function Attrs: norecurse nounwind readonly +define signext i32 @testComplexISEL() #0 { +entry: + %0 = load i32, i32* @b, align 4, !tbaa !1 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %if.end, label %cleanup + +if.end: + %1 = load i32, i32* @a, align 4, !tbaa !1 + %conv = sext i32 %1 to i64 + %2 = inttoptr i64 %conv to i32 (...)* + %cmp = icmp eq i32 (...)* %2, bitcast (i32 ()* @testComplexISEL to i32 (...)*) + %conv3 = zext i1 %cmp to i32 + br label %cleanup + +cleanup: + %retval.0 = phi i32 [ %conv3, %if.end ], [ 1, %entry ] + ret i32 %retval.0 + +; CHECK-LABEL: @testComplexISEL +; CHECK: bc 12, 2, .LBB +; CHECK-NEXT: b .LBB +; CHECK: addi r3, r12, 0 +; CHECK: clrldi r3, r3, 32 +; CHECK-NEXT: blr +} + +!1 = !{!2, !2, i64 0} +!2 = !{!"int", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"} Index: test/CodeGen/PowerPC/fold-zero.ll =================================================================== --- test/CodeGen/PowerPC/fold-zero.ll +++ test/CodeGen/PowerPC/fold-zero.ll @@ -1,5 +1,6 @@ ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-crbits | FileCheck %s ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck -check-prefix=CHECK-CRB %s +; RUN: llc -verify-machineinstrs -ppc-gen-isel=false < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -7,19 +8,31 @@ %x = select i1 %a, i32 %c, i32 0 ret i32 %x -; CHECK: @test1 +; CHECK-LABEL: @test1 ; CHECK-NOT: li {{[0-9]+}}, 0 ; CHECK: isel 3, 0, ; CHECK: blr +; CHECK-NO-ISEL-LABEL: @test1 +; CHECK-NO-ISEL: li 3, 0 +; CHECK-NO-ISEL-NEXT: bc 12, 1, .LBB +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 4, 0 +; CHECK-NO-ISEL-NEXT: blr } define i32 @test2(i1 %a, i32 %c) nounwind { %x = select i1 %a, i32 0, i32 %c ret i32 %x -; CHECK-CRB: @test2 +; CHECK-CRB-LABEL: @test2 ; CHECK-CRB-NOT: li {{[0-9]+}}, 0 ; CHECK-CRB: isel 3, 0, ; CHECK-CRB: blr +; CHECK-NO-ISEL-LABEL: @test2 +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL: ori 3, 4, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 0, 0 +; CHECK-NO-ISEL-NEXT: blr } Index: test/CodeGen/PowerPC/i1-ext-fold.ll =================================================================== --- test/CodeGen/PowerPC/i1-ext-fold.ll +++ test/CodeGen/PowerPC/i1-ext-fold.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -11,11 +12,18 @@ ret i32 %shl ; CHECK-LABEL: @foo +; CHECK-NO-ISEL-LABEL: @foo ; CHECK-DAG: cmpw ; CHECK-DAG: li [[REG1:[0-9]+]], 0 ; CHECK-DAG: li [[REG2:[0-9]+]], 16 ; CHECK: isel 3, [[REG2]], [[REG1]], ; CHECK: blr + +; CHECK-NO-ISEL: bc 12, 0, .LBB +; CHECK-NO-ISEL: ori 3, 5, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 12, 0 +; CHECK-NO-ISEL-NEXT: blr } ; Function Attrs: nounwind readnone @@ -28,11 +36,18 @@ ret i32 %add1 ; CHECK-LABEL: @foo2 +; CHECK-NO-ISEL-LABEL: @foo2 ; CHECK-DAG: cmpw ; CHECK-DAG: li [[REG1:[0-9]+]], 5 ; CHECK-DAG: li [[REG2:[0-9]+]], 21 ; CHECK: isel 3, [[REG2]], [[REG1]], ; CHECK: blr + +; CHECK-NO-ISEL: bc 12, 0, .LBB +; CHECK-NO-ISEL: ori 3, 5, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 12, 0 +; CHECK-NO-ISEL-NEXT: blr } ; Function Attrs: nounwind readnone @@ -44,10 +59,17 @@ ret i32 %shl ; CHECK-LABEL: @foo3 +; CHECK-NO-ISEL-LABEL: @foo3 ; CHECK-DAG: cmpw ; CHECK-DAG: li [[REG1:[0-9]+]], 16 ; CHECK: isel 3, 0, [[REG1]], ; CHECK: blr + +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL: ori 3, 5, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 0, 0 +; CHECK-NO-ISEL-NEXT: blr } attributes #0 = { nounwind readnone } Index: test/CodeGen/PowerPC/i64_fp_round.ll =================================================================== --- test/CodeGen/PowerPC/i64_fp_round.ll +++ test/CodeGen/PowerPC/i64_fp_round.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-fpcvt < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-fpcvt -ppc-gen-isel=false < %s | FileCheck %s --check-prefix=CHECK-NO-ISEL target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -12,10 +13,16 @@ ; Note that only parts of the sequence are checked for here, to allow ; for minor code generation differences. +;CHECK-LABEL: test +;CHECK-NO-ISEL-LABEL: test ; CHECK: sradi [[REG1:[0-9]+]], 3, 53 ; CHECK: addi [[REG2:[0-9]+]], [[REG1]], 1 ; CHECK: cmpldi [[REG2]], 1 ; CHECK: isel [[REG3:[0-9]+]], {{[0-9]+}}, 3, 1 +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL: ori 11, 3, 0 +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL: addi 11, 4, 0 ; CHECK: std [[REG3]], -{{[0-9]+}}(1) Index: test/CodeGen/PowerPC/ifcvt.ll =================================================================== --- test/CodeGen/PowerPC/ifcvt.ll +++ test/CodeGen/PowerPC/ifcvt.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -verify-machineinstrs -ppc-gen-isel=false | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -18,10 +19,17 @@ %add37 = add nsw i32 %conv29, %a br label %cond.end -; CHECK: @test +; CHECK-LABEL: @test +; CHECK-NO-ISEL-LABEL: @test ; CHECK: add [[REG:[0-9]+]], ; CHECK: subf [[REG2:[0-9]+]], ; CHECK: isel {{[0-9]+}}, [[REG]], [[REG2]], +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL: addi 5, 6, 0 +; CHECK-NO-ISEL: extsh 5, 5 +; CHECK-NO-ISEL-NEXT: add 3, 3, 5 +; CHECK-NO-ISEL-NEXT: blr cond.end: ; preds = %cond.false, %cond.true %cond = phi i32 [ %sub34, %cond.true ], [ %add37, %cond.false ] Index: test/CodeGen/PowerPC/isel.ll =================================================================== --- test/CodeGen/PowerPC/isel.ll +++ test/CodeGen/PowerPC/isel.ll @@ -2,14 +2,21 @@ target triple = "powerpc64-unknown-linux-gnu" ; RUN: llc -verify-machineinstrs -mcpu=a2 < %s | FileCheck %s ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s define i64 @test1(i64 %a, i64 %b, i64 %c, i64 %d) { entry: %p = icmp uge i64 %a, %b %x = select i1 %p, i64 %c, i64 %d ret i64 %x -; CHECK: @test1 +; CHECK-LABEL: @test1 +; CHECK-NO-ISEL-LABEL: @test1 ; CHECK: isel +; CHECK-NO-ISEL: bc 12, 0, .LBB +; CHECK-NO-ISEL: ori 3, 5, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 6, 0 +; CHECK-NO-ISEL-NEXT: blr } define i32 @test2(i32 %a, i32 %b, i32 %c, i32 %d) { @@ -17,7 +24,13 @@ %p = icmp uge i32 %a, %b %x = select i1 %p, i32 %c, i32 %d ret i32 %x -; CHECK: @test2 +; CHECK-LABEL: @test2 +; CHECK-NO-ISEL-LABEL: @test2 ; CHECK: isel +; CHECK-NO-ISEL: bc 12, 0, .LBB +; CHECK-NO-ISEL: ori 3, 5, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 6, 0 +; CHECK-NO-ISEL-NEXT: blr } Index: test/CodeGen/PowerPC/optcmp.ll =================================================================== --- test/CodeGen/PowerPC/optcmp.ll +++ test/CodeGen/PowerPC/optcmp.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 -mattr=-crbits -disable-ppc-cmp-opt=0 | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 -mattr=-crbits -disable-ppc-cmp-opt=0 -ppc-gen-isel=false | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -34,9 +35,14 @@ %cond = select i1 %cmp, i64 %a, i64 %b ret i64 %cond -; CHECK: @fool +; CHECK-LABEL: @fool +; CHECK-NO-ISEL-LABEL: @fool ; CHECK: subf. [[REG:[0-9]+]], 4, 3 ; CHECK: isel 3, 3, 4, 1 +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL: ori 3, 4, 0 +; CHECK-NO-ISEL: b .LBB + ; CHECK: std [[REG]], 0(5) } @@ -48,9 +54,13 @@ %cond = select i1 %cmp, i64 %a, i64 %b ret i64 %cond -; CHECK: @foolb +; CHECK-LABEL: @foolb +; CHECK-NO-ISEL-LABEL: @foolb ; CHECK: subf. [[REG:[0-9]+]], 4, 3 ; CHECK: isel 3, 4, 3, 1 +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL addi: 3, 4, 0 ; CHECK: std [[REG]], 0(5) } @@ -62,9 +72,13 @@ %cond = select i1 %cmp, i64 %a, i64 %b ret i64 %cond -; CHECK: @foolc +; CHECK-LABEL: @foolc +; CHECK-NO-ISEL-LABEL: @foolc ; CHECK: subf. [[REG:[0-9]+]], 3, 4 ; CHECK: isel 3, 3, 4, 0 +; CHECK-NO-ISEL: bc 12, 0, .LBB +; CHECK-NO-ISEL: ori 3, 4, 0 +; CHECK-NO-ISEL: b .LBB ; CHECK: std [[REG]], 0(5) } @@ -76,9 +90,13 @@ %cond = select i1 %cmp, i64 %a, i64 %b ret i64 %cond -; CHECK: @foold +; CHECK-LABEL: @foold +; CHECK-NO-ISEL-LABEL: @foold ; CHECK: subf. [[REG:[0-9]+]], 3, 4 ; CHECK: isel 3, 3, 4, 1 +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL: ori 3, 4, 0 +; CHECK-NO-ISEL: b .LBB ; CHECK: std [[REG]], 0(5) } @@ -90,9 +108,13 @@ %cond = select i1 %cmp, i64 %a, i64 %b ret i64 %cond -; CHECK: @foold2 +; CHECK-LABEL: @foold2 +; CHECK-NO-ISEL-LABEL: @foold2 ; CHECK: subf. [[REG:[0-9]+]], 4, 3 ; CHECK: isel 3, 3, 4, 0 +; CHECK-NO-ISEL: bc 12, 0, .LBB +; CHECK-NO-ISEL: ori 3, 4, 0 +; CHECK-NO-ISEL: b .LBB ; CHECK: std [[REG]], 0(5) } Index: test/CodeGen/PowerPC/p8-isel-sched.ll =================================================================== --- test/CodeGen/PowerPC/p8-isel-sched.ll +++ test/CodeGen/PowerPC/p8-isel-sched.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr8 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -24,9 +25,18 @@ ; Make sure that we don't schedule all of the isels together, they should be ; intermixed with the adds because each isel starts a new dispatch group. ; CHECK-LABEL: @foo +; CHECK-NO-ISEL-LABEL: @foo ; CHECK: isel +; CHECK-NO-ISEL: bc 12, 2, .LBB +; CHECK-NO-ISEL: ori 7, 12, 0 +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL: addi 7, 11, 0 ; CHECK: addi ; CHECK: isel +; CHECK-NO-ISEL: bc 12, 2, .LBB +; CHECK-NO-ISEL: ori 10, 11, 0 +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL: addi 10, 12, 0 ; CHECK: blr attributes #0 = { nounwind } Index: test/CodeGen/PowerPC/ppc-crbits-onoff.ll =================================================================== --- test/CodeGen/PowerPC/ppc-crbits-onoff.ll +++ test/CodeGen/PowerPC/ppc-crbits-onoff.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -12,10 +13,15 @@ ret i32 %and ; CHECK-LABEL: @crbitsoff +; CHECK-NO-ISEL-LABEL: @crbitsoff ; CHECK-DAG: cmplwi {{[0-9]+}}, 3, 0 ; CHECK-DAG: li [[REG2:[0-9]+]], 1 ; CHECK-DAG: cntlzw [[REG3:[0-9]+]], ; CHECK: isel [[REG4:[0-9]+]], 0, [[REG2]] +; CHECK-NO-ISEL: bc 12, 2, .LBB +; CHECK-NO-ISEL: ori 4, 5, 0 +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL: addi 4, 0, 0 ; CHECK: and 3, [[REG4]], [[REG3]] ; CHECK: blr } @@ -29,11 +35,16 @@ ret i32 %and ; CHECK-LABEL: @crbitson +; CHECK-NO-ISEL-LABEL: @crbitson ; CHECK-DAG: cmpwi {{[0-9]+}}, 3, 0 ; CHECK-DAG: cmpwi {{[0-9]+}}, 4, 0 ; CHECK-DAG: li [[REG2:[0-9]+]], 1 ; CHECK-DAG: crorc [[REG3:[0-9]+]], ; CHECK: isel 3, 0, [[REG2]], [[REG3]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 0, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } Index: test/CodeGen/PowerPC/select-i1-vs-i1.ll =================================================================== --- test/CodeGen/PowerPC/select-i1-vs-i1.ll +++ test/CodeGen/PowerPC/select-i1-vs-i1.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -15,10 +16,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32slt +; CHECK-NO-ISEL-LABEL: @testi32slt ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -30,11 +37,16 @@ %cond = select i1 %cmp3, i32 %a1, i32 %a2 ret i32 %cond -; CHECK-LABEL: @testi32ult +; CHECK-NO-ISEL-LABEL: @testi32ult ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -47,10 +59,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32sle +; CHECK-NO-ISEL-LABEL: @testi32sle ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -63,10 +81,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32ule +; CHECK-NO-ISEL-LABEL: @testi32ule ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -79,10 +103,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32eq +; CHECK-NO-ISEL-LABEL: @testi32eq ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: creqv [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -95,10 +125,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32sge +; CHECK-NO-ISEL-LABEL: @testi32sge ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -111,10 +147,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32uge +; CHECK-NO-ISEL-LABEL: @testi32uge ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -127,10 +169,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32sgt +; CHECK-NO-ISEL-LABEL: @testi32sgt ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -143,10 +191,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32ugt +; CHECK-NO-ISEL-LABEL: @testi32ugt ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -159,10 +213,16 @@ ret i32 %cond ; CHECK-LABEL: @testi32ne +; CHECK-NO-ISEL-LABEL: @testi32ne ; CHECK-DAG: cmpw {{[0-9]+}}, 5, 6 ; CHECK-DAG: cmpw {{[0-9]+}}, 3, 4 ; CHECK: crxor [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -175,10 +235,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64slt +; CHECK-NO-ISEL-LABEL: @testi64slt ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -191,10 +257,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64ult +; CHECK-NO-ISEL-LABEL: @testi64ult ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -207,10 +279,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64sle +; CHECK-NO-ISEL-LABEL: @testi64sle ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -223,10 +301,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64ule +; CHECK-NO-ISEL-LABEL: @testi64ule ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -239,10 +323,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64eq +; CHECK-NO-ISEL-LABEL: @testi64eq ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: creqv [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -255,10 +345,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64sge +; CHECK-NO-ISEL-LABEL: @testi64sge ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -271,10 +367,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64uge +; CHECK-NO-ISEL-LABEL: @testi64uge ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crorc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -287,10 +389,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64sgt +; CHECK-NO-ISEL-LABEL: @testi64sgt ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -303,10 +411,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64ugt +; CHECK-NO-ISEL-LABEL: @testi64ugt ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crandc [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } @@ -319,10 +433,16 @@ ret i64 %cond ; CHECK-LABEL: @testi64ne +; CHECK-NO-ISEL-LABEL: @testi64ne ; CHECK-DAG: cmpd {{([0-9]+, )?}}5, 6 ; CHECK-DAG: cmpd {{([0-9]+, )?}}3, 4 ; CHECK: crxor [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK: isel 3, 7, 8, [[REG1]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 3, 8, 0 +; CHECK-NO-ISEL-NEXT: blr +; CHECK-NO-ISEL: addi 3, 7, 0 +; CHECK-NO-ISEL-NEXT: blr ; CHECK: blr } Index: test/CodeGen/PowerPC/subreg-postra-2.ll =================================================================== --- test/CodeGen/PowerPC/subreg-postra-2.ll +++ test/CodeGen/PowerPC/subreg-postra-2.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -31,10 +32,15 @@ br i1 %tobool419, label %if.end421, label %if.then420 ; CHECK-LABEL: @jbd2_journal_commit_transaction +; CHECK-NO-ISEL-LABEL: @jbd2_journal_commit_transaction ; CHECK: andi. ; CHECK: crmove [[REG:[0-9]+]], 1 ; CHECK: stdcx. ; CHECK: isel {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}, [[REG]] +; CHECK-NO-ISEL: bc 12, 20, .LBB +; CHECK-NO-ISEL: ori 4, 7, 0 +; CHECK-NO-ISEL-NEXT: b .LBB +; CHECK-NO-ISEL: addi 4, 3, 0 if.then420: ; preds = %while.end418 unreachable Index: test/CodeGen/PowerPC/subreg-postra.ll =================================================================== --- test/CodeGen/PowerPC/subreg-postra.ll +++ test/CodeGen/PowerPC/subreg-postra.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -145,10 +146,15 @@ br i1 %inp8, label %while.end418, label %while.body392 ; CHECK-LABEL: @jbd2_journal_commit_transaction +; CHECK-NO-ISEL-LABEL: @jbd2_journal_commit_transaction ; CHECK: andi. ; CHECK: crmove ; CHECK: stdcx. ; CHECK: isel {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}, +; CHECK-NO-ISEL: bc 12, 1, .LBB +; CHECK-NO-ISEL: ori 30, 3, 0 +; CHECK-NO-ISEL: b .LBB + while.end418: ; preds = %wait_on_buffer.exit1319, %do.body378 %err.4.lcssa = phi i32 [ %inp2, %do.body378 ], [ %.err.4, %wait_on_buffer.exit1319 ]