Index: lib/Target/PowerPC/PPCExpandISEL.cpp =================================================================== --- lib/Target/PowerPC/PPCExpandISEL.cpp +++ lib/Target/PowerPC/PPCExpandISEL.cpp @@ -124,9 +124,6 @@ #endif bool runOnMachineFunction(MachineFunction &MF) override { - if (!isExpandISELEnabled(MF)) - return false; - DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n"); initialize(MF); @@ -190,24 +187,56 @@ } void PPCExpandISEL::expandAndMergeISELs() { - for (auto &BlockList : ISELInstructions) { - DEBUG(dbgs() << "Expanding ISEL instructions in BB#" << BlockList.first - << "\n"); + bool ExpandISELEnabled = isExpandISELEnabled(*MF); + for (auto &BlockList : ISELInstructions) { + DEBUG(dbgs() << "ISEL instructions in BB#" << BlockList.first << "\n"); BlockISELList &CurrentISELList = BlockList.second; auto I = CurrentISELList.begin(); auto E = CurrentISELList.end(); while (I != E) { - BlockISELList SubISELList; - - SubISELList.push_back(*I++); - - // Collect the ISELs that can be merged together. - while (I != E && canMerge(SubISELList.back(), *I)) - SubISELList.push_back(*I++); - - expandMergeableISELs(SubISELList); + assert(isISEL(**I) && "Expecting an ISEL instruction"); + MachineOperand &Dest = (*I)->getOperand(0); + MachineOperand &TrueValue = (*I)->getOperand(1); + MachineOperand &FalseValue = (*I)->getOperand(2); + + // Special case 1, all registers used by ISEL are the same one. + if (useSameRegister(Dest, TrueValue) && + useSameRegister(Dest, FalseValue)) { + DEBUG(dbgs() << "Remove redudant ISEL instruction: " << **I << "\n"); + NumRemoved++; + (*I)->eraseFromParent(); + I++; + } else if (useSameRegister(TrueValue, FalseValue)) { + // Special case 2, the two input registers used by ISEL are the same. + MachineBasicBlock *MBB = (*I)->getParent(); + DEBUG(dbgs() << "Fold the ISEL instruction to an unconditonal copy:\n"); + DEBUG(dbgs() << "ISEL: " << **I << "\n"); + NumFolded++; + BuildMI(*MBB, (*I), dl, TII->get(isISEL8(**I) ? PPC::ADDI8 : PPC::ADDI)) + .add(Dest) + .add(TrueValue) + .add(MachineOperand::CreateImm(0)); + (*I)->eraseFromParent(); + I++; + } else { // Normal cases + if (ExpandISELEnabled) { + DEBUG(dbgs() << "Expand mergeable ISEL instructions:\n"); + DEBUG(dbgs() << "ISEL: " << **I << "\n"); + BlockISELList SubISELList; + SubISELList.push_back(*I++); + // Collect the ISELs that can be merged together. + while (I != E && canMerge(SubISELList.back(), *I)) { + DEBUG(dbgs() << "ISEL: " << **I << "\n"); + SubISELList.push_back(*I++); + } + + expandMergeableISELs(SubISELList); + } else { + I++; // leave the ISEL as it is + } + } } } } Index: test/CodeGen/PowerPC/expand-contiguous-isel.ll =================================================================== --- test/CodeGen/PowerPC/expand-contiguous-isel.ll +++ test/CodeGen/PowerPC/expand-contiguous-isel.ll @@ -120,7 +120,8 @@ br label %while.cond.outer ; CHECK-LABEL: @_Z3fn1N4llvm9StringRefE -; CHECK-GEN-ISEL-TRUE: isel [[SAME:r[0-9]+]], [[SAME]], [[SAME]] +; Unecessary ISEL (all the registers are the same) is always removed +; CHECK-GEN-ISEL-TRUE-NOT: isel [[SAME:r[0-9]+]], [[SAME]], [[SAME]] ; CHECK-GEN-ISEL-TRUE: isel [[SAME:r[0-9]+]], {{r[0-9]+}}, [[SAME]] ; CHECK: bc 12, eq, [[TRUE:.LBB[0-9]+]] ; CHECK-NEXT: b [[SUCCESSOR:.LBB[0-9]+]] Index: test/CodeGen/PowerPC/expand-isel-9.mir =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/expand-isel-9.mir @@ -0,0 +1,54 @@ +# This file tests the scenario: ISEL RX, RY, RY, CR (X != 0 && Y != 0) +# It is folded into a copy (%RX = ADDI %RY, 0) +# RUN: llc -ppc-gen-isel=true -run-pass ppc-expand-isel -o - %s | FileCheck %s + +--- | + target datalayout = "E-m:e-i64:64-n32:64" + target triple = "powerpc64-unknown-linux-gnu" + define signext i32 @testExpandISEL(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 + } + +... +--- +name: testExpandISEL +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: + - { reg: '%x3' } + - { reg: '%x4' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.entry: + liveins: %x3, %x4 + + %r5 = ADDI %r3, 1 + %cr0 = CMPWI %r3, 0 + %r3 = ISEL %r4, %r4, %cr0gt + ; Test fold ISEL to a copy + ; CHECK: %r3 = ADDI %r4, 0 + + %x3 = EXTSW_32_64 %r3 + +...