diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2371,9 +2371,13 @@ // Find new register class to use. MachineOperand FalseReg = MI.getOperand(Invert ? 2 : 1); + MachineOperand TrueReg = MI.getOperand(Invert ? 1 : 2); Register DestReg = MI.getOperand(0).getReg(); - const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg()); - if (!MRI.constrainRegClass(DestReg, PreviousClass)) + const TargetRegisterClass *FalseClass = MRI.getRegClass(FalseReg.getReg()); + const TargetRegisterClass *TrueClass = MRI.getRegClass(TrueReg.getReg()); + if (!MRI.constrainRegClass(DestReg, FalseClass)) + return nullptr; + if (!MRI.constrainRegClass(DestReg, TrueClass)) return nullptr; // Create a new predicated version of DefMI. diff --git a/llvm/test/CodeGen/ARM/movc-peephole.mir b/llvm/test/CodeGen/ARM/movc-peephole.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/ARM/movc-peephole.mir @@ -0,0 +1,41 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -run-pass=peephole-opt %s -o - -verify-machineinstrs | FileCheck %s + +# Make sure the MOVCC to conditional instruction peephole doesn't change the +# register class to one that's invalid. + +--- | + target triple = "armv7-unknown-unknown" + define i32 @test(i32 %x, i32 %y) { + ret i32 undef + } +... +--- +name: test +tracksRegLiveness: true +body: | + bb.0 (%ir-block.0): + liveins: $r0, $r1 + ; CHECK-LABEL: name: test + ; CHECK: liveins: $r0, $r1 + ; CHECK: [[COPY:%[0-9]+]]:gpr = COPY $r0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $r1 + ; CHECK-NEXT: [[MOVsi:%[0-9]+]]:gpr = MOVsi [[COPY1]], 27, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[ORRrsi:%[0-9]+]]:gpr = ORRrsi [[MOVsi]], [[COPY1]], 234, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[MOVsi1:%[0-9]+]]:gpr = MOVsi [[COPY1]], 155, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[ORRrsi1:%[0-9]+]]:gprnopc = ORRrsi killed [[MOVsi1]], killed [[MOVsi]], 106, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: TSTri [[COPY1]], 1, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[UXTH:%[0-9]+]]:gprnopc = UXTH killed [[ORRrsi1]], 0, 0 /* CC::eq */, $cpsr, implicit [[ORRrsi]](tied-def 0) + ; CHECK-NEXT: $r0 = COPY killed [[UXTH]] + ; CHECK-NEXT: BX_RET 14 /* CC::al */, $noreg, implicit $r0 + %0:gpr = COPY $r0 + %1:gpr = COPY $r1 + %2:gpr = MOVsi %1:gpr, 27, 14, $noreg, $noreg + %3:gpr = ORRrsi %2:gpr, %1:gpr, 234, 14, $noreg, $noreg + %4:gpr = MOVsi %1:gpr, 155, 14, $noreg, $noreg + %5:gprnopc = ORRrsi killed %4:gpr, killed %2:gpr, 106, 14, $noreg, $noreg + %6:gprnopc = UXTH killed %5:gprnopc, 0, 14, $noreg + TSTri %1:gpr, 1, 14, $noreg, implicit-def $cpsr + %7:gpr = MOVCCr %3:gpr, killed %6:gprnopc, 0, $cpsr + $r0 = COPY killed %7 + BX_RET 14, $noreg, implicit $r0