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 @@ -585,15 +585,30 @@ MRI->constrainRegClass(DstReg, DstRC); } + // SubReg defs are illegal in machine SSA phase, + // we should not generate SubReg defs. + // + // For example, for the instructions: + // + // %1:g8rc_and_g8rc_nox0 = EXTSW %0:g8rc + // %3:gprc_and_gprc_nor0 = COPY %0.sub_32:g8rc + // + // We should generate: + // + // %1:g8rc_and_g8rc_nox0 = EXTSW %0:g8rc + // %6:gprc_and_gprc_nor0 = COPY %1.sub_32:g8rc_and_g8rc_nox0 + // %3:gprc_and_gprc_nor0 = COPY %6:gprc_and_gprc_nor0 + // + if (UseSrcSubIdx) + RC = MRI->getRegClass(UseMI->getOperand(0).getReg()); + Register NewVR = MRI->createVirtualRegister(RC); - MachineInstr *Copy = BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(), - TII->get(TargetOpcode::COPY), NewVR) + BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(), + TII->get(TargetOpcode::COPY), NewVR) .addReg(DstReg, 0, SubIdx); - // SubIdx applies to both SrcReg and DstReg when UseSrcSubIdx is set. - if (UseSrcSubIdx) { - Copy->getOperand(0).setSubReg(SubIdx); - Copy->getOperand(0).setIsUndef(); - } + if (UseSrcSubIdx) + UseMO->setSubReg(0); + UseMO->setReg(NewVR); ++NumReuse; Changed = true; diff --git a/llvm/test/CodeGen/PowerPC/peephole-subreg-def.mir b/llvm/test/CodeGen/PowerPC/peephole-subreg-def.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/peephole-subreg-def.mir @@ -0,0 +1,63 @@ +# 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 + +# This tests to make sure that we do not generate subreg def +# as it is illegal to generate subreg defs in machine SSA phase. + +--- | + declare i64 @strlen() + + define dso_local fastcc void @test_peephole_subreg_def() { + 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: test_peephole_subreg_def +alignment: 16 +tracksRegLiveness: true +frameInfo: + maxAlignment: 1 + hasCalls: true +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x2 + ; CHECK-LABEL: name: test_peephole_subreg_def + ; 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) + 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 + %0:g8rc = COPY $x3 + %1:g8rc_and_g8rc_nox0 = EXTSW %0 + %2:g8rc = LI8 0 + STB8 %2, 0, killed %1 :: (store 1 into %ir.arrayidx419) + %3:gprc_and_gprc_nor0 = COPY %0.sub_32 + %4:gprc = ADDI killed %3, 1 + %5:g8rc_and_g8rc_nox0 = EXTSW_32_64 killed %4 + STB8 %2, 0, killed %5 :: (store 1 into %ir.arrayidx421) + +...