Index: llvm/lib/Target/X86/X86CmovConversion.cpp =================================================================== --- llvm/lib/Target/X86/X86CmovConversion.cpp +++ llvm/lib/Target/X86/X86CmovConversion.cpp @@ -115,6 +115,7 @@ MachineRegisterInfo *MRI = nullptr; const TargetInstrInfo *TII = nullptr; const TargetRegisterInfo *TRI = nullptr; + MachineLoopInfo *MLI = nullptr; TargetSchedModel TSchedModel; /// List of consecutive CMOV instructions. @@ -165,7 +166,7 @@ << "**********\n"); bool Changed = false; - MachineLoopInfo &MLI = getAnalysis(); + MLI = &getAnalysis(); const TargetSubtargetInfo &STI = MF.getSubtarget(); MRI = &MF.getRegInfo(); TII = STI.getInstrInfo(); @@ -221,7 +222,7 @@ //===--------------------------------------------------------------------===// // Build up the loops in pre-order. - SmallVector Loops(MLI.begin(), MLI.end()); + SmallVector Loops(MLI->begin(), MLI->end()); // Note that we need to check size on each iteration as we accumulate child // loops. for (int i = 0; i < (int)Loops.size(); ++i) @@ -848,6 +849,12 @@ // Now remove the CMOV(s). MBB->erase(MIItBegin, MIItEnd); + + // Add new basic blocks to MachineLoopInfo. + if (MachineLoop *L = MLI->getLoopFor(MBB)) { + L->addBasicBlockToLoop(FalseMBB, MLI->getBase()); + L->addBasicBlockToLoop(SinkMBB, MLI->getBase()); + } } INITIALIZE_PASS_BEGIN(X86CmovConverterPass, DEBUG_TYPE, "X86 cmov Conversion", Index: llvm/test/CodeGen/X86/x86-cmov-converter.ll =================================================================== --- llvm/test/CodeGen/X86/x86-cmov-converter.ll +++ llvm/test/CodeGen/X86/x86-cmov-converter.ll @@ -483,4 +483,37 @@ ret i32 %r } +; Check that when a CMOVrm is in a loop, and there are CMOVrrs in the same +; block, converting the CMOVrm doesn't inhibit conversion of CMOVrrs. +@begin = external global i32* +@end = external global i32* + +define void @test_memoperand_loop(i32 %data) #0 { +; CHECK-LABEL: test_memoperand_loop +entry: +; CHECK-NOT: cmov + %begin = load i32*, i32** @begin, align 8 + %end = load i32*, i32** @end, align 8 + br label %loop.body + +loop.body: + %phi.iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.body ] + %phi.ptr = phi i32* [ %begin, %entry ], [ %dst2, %loop.body ] + %gep1 = getelementptr inbounds i32, i32 *%phi.ptr, i64 2 + %cmp1 = icmp ugt i32* %gep1, %end + %begin_dup = load i32*, i32** @begin, align 8 + %dst1 = select i1 %cmp1, i32* %gep1, i32* %begin_dup + store i32 %data, i32 *%dst1, align 4 + %gep2 = getelementptr inbounds i32, i32 *%dst1, i64 2 + %cmp2 = icmp ugt i32* %gep2, %end + %dst2 = select i1 %cmp2, i32* %gep2, i32* %begin + store i32 %data, i32 *%dst2, align 4 + %iv.next = add i32 %phi.iv, 1 + %cond = icmp slt i32 %iv.next, 1024 + br i1 %cond, label %loop.body, label %exit + +exit: + ret void +} + attributes #0 = {"target-cpu"="x86-64"}