diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp --- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp +++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp @@ -571,10 +571,31 @@ if (UI.isPHI()) PHIBBs.insert(UI.getParent()); + bool DisableSubReg = false; const TargetRegisterClass *RC = MRI->getRegClass(SrcReg); for (unsigned i = 0, e = Uses.size(); i != e; ++i) { MachineOperand *UseMO = Uses[i]; MachineInstr *UseMI = UseMO->getParent(); + + // Sub-reg defs are illegal in machine SSA phase, + // so we should generate defs without subreg. + // + // For example, for the instructions: + // + // %2:g8rc_and_g8rc_nox0 = EXTSW %1:g8rc + // %4:gprc_and_gprc_nor0 = COPY %1.sub_32:g8rc + // + // We should generate: + // + // %7:gprc_and_gprc_nor0 = COPY %2.sub_32:g8rc_and_g8rc_nox0 + // %4:gprc_and_gprc_nor0 = COPY %7:gprc_and_gprc_nor0 + // + if (UseSrcSubIdx && (UseMI->getOpcode() == TargetOpcode::COPY)) { + UseSrcSubIdx = false; + DisableSubReg = true; + RC = MRI->getRegClass(UseMI->getOperand(0).getReg()); + } + MachineBasicBlock *UseMBB = UseMI->getParent(); if (PHIBBs.count(UseMBB)) continue; @@ -593,6 +614,8 @@ if (UseSrcSubIdx) { Copy->getOperand(0).setSubReg(SubIdx); Copy->getOperand(0).setIsUndef(); + } else if (DisableSubReg) { + UseMO->setSubReg(0); } UseMO->setReg(NewVR); ++NumReuse; diff --git a/llvm/test/CodeGen/PowerPC/peephole-subreg.mir b/llvm/test/CodeGen/PowerPC/peephole-subreg.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/peephole-subreg.mir @@ -0,0 +1,95 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=powerpc64le -simplify-mir -verify-machineinstrs \ +# RUN: -run-pass=peephole-opt %s -o - | FileCheck %s + +--- | + declare i64 @strlen() local_unnamed_addr + + define dso_local fastcc void @check_format_info_main() unnamed_addr { + entry: + %0 = zext i8 undef to i32 + %cond = icmp eq i32 %0, 0 + br i1 %cond, label %if.then32, label %if.end40 + + if.then32: ; preds = %entry + unreachable + + if.end40: ; preds = %entry + %call413 = call i64 @strlen() + %sext1679 = shl i64 %call413, 32 + %idxprom418 = ashr exact i64 %sext1679, 32 + %arrayidx419 = getelementptr inbounds [256 x i8], [256 x i8]* null, i64 0, i64 %idxprom418 + store i8 0, i8* %arrayidx419, align 1 + %sext1680 = add i64 %sext1679, 4294967296 + %idxprom420 = ashr exact i64 %sext1680, 32 + %arrayidx421 = getelementptr inbounds [256 x i8], [256 x i8]* null, i64 0, i64 %idxprom420 + store i8 0, i8* %arrayidx421, align 1 + unreachable + } + +... +--- +name: check_format_info_main +alignment: 16 +tracksRegLiveness: true +registers: + - { id: 0, class: crbitrc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc_and_g8rc_nox0 } + - { id: 3, class: g8rc } + - { id: 4, class: gprc_and_gprc_nor0 } + - { id: 5, class: gprc } + - { id: 6, class: g8rc_and_g8rc_nox0 } +frameInfo: + maxAlignment: 1 + hasCalls: true +machineFunctionInfo: {} +body: | + ; CHECK-LABEL: name: check_format_info_main + ; CHECK: bb.0.entry: + ; CHECK: successors: %bb.1(0x30000000), %bb.2(0x50000000) + ; CHECK: [[CRUNSET:%[0-9]+]]:crbitrc = CRUNSET + ; CHECK: BC killed [[CRUNSET]], %bb.2 + ; CHECK: B %bb.1 + ; CHECK: bb.1.if.then32: + ; CHECK: successors: + ; CHECK: bb.2.if.end40: + ; CHECK: liveins: $x2 + ; CHECK: ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 + ; CHECK: BL8_NOP @strlen, csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $x2, implicit-def $r1, implicit-def $x3 + ; CHECK: ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 + ; CHECK: [[COPY:%[0-9]+]]:g8rc = COPY $x3 + ; CHECK: [[EXTSW:%[0-9]+]]:g8rc_and_g8rc_nox0 = EXTSW [[COPY]] + ; CHECK: [[LI8_:%[0-9]+]]:g8rc = LI8 0 + ; CHECK: STB8 [[LI8_]], 0, [[EXTSW]] :: (store 1 into %ir.arrayidx419) + ; CHECK: [[COPY1:%[0-9]+]]:gprc_and_gprc_nor0 = COPY [[EXTSW]].sub_32 + ; CHECK: [[COPY2:%[0-9]+]]:gprc_and_gprc_nor0 = COPY [[COPY1]] + ; CHECK: [[ADDI:%[0-9]+]]:gprc = ADDI killed [[COPY2]], 1 + ; CHECK: [[EXTSW_32_64_:%[0-9]+]]:g8rc_and_g8rc_nox0 = EXTSW_32_64 killed [[ADDI]] + ; CHECK: STB8 [[LI8_]], 0, killed [[EXTSW_32_64_]] :: (store 1 into %ir.arrayidx421) + bb.0.entry: + successors: %bb.1(0x30000000), %bb.2(0x50000000) + + %0:crbitrc = CRUNSET + BC killed %0, %bb.2 + B %bb.1 + + bb.1.if.then32: + successors: + + + bb.2.if.end40: + liveins: $x2 + ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 + BL8_NOP @strlen, csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $x2, implicit-def $r1, implicit-def $x3 + ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 + %1:g8rc = COPY $x3 + %2:g8rc_and_g8rc_nox0 = EXTSW %1 + %3:g8rc = LI8 0 + STB8 %3, 0, killed %2 :: (store 1 into %ir.arrayidx419) + %4:gprc_and_gprc_nor0 = COPY %1.sub_32 + %5:gprc = ADDI killed %4, 1 + %6:g8rc_and_g8rc_nox0 = EXTSW_32_64 killed %5 + STB8 %3, 0, killed %6 :: (store 1 into %ir.arrayidx421) + +...