From 082fa56819048770e76fef8bca4ea5de3c3532ba Mon Sep 17 00:00:00 2001 From: John Brawn Date: Wed, 13 Oct 2021 13:59:42 +0100 Subject: [PATCH] [ARM] Fix MOVCC peephole to not use an incorrect register class The MOVCC peephole eliminates a MOVCC by making one of its inputs a conditional instruction, but when doing this it should be using both inputs of the MOVCC to decide on the register class to use as otherwise we can get an error when using -verify-machineinstrs. Differential Revision: https://reviews.llvm.org/D111714 --- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 8 +++-- llvm/test/CodeGen/ARM/movc-peephole.mir | 41 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/ARM/movc-peephole.mir diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index b2363ee2ef57e..f19cf84253f00 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2371,9 +2371,13 @@ ARMBaseInstrInfo::optimizeSelect(MachineInstr &MI, // 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 index 0000000000000..6de013b260fc6 --- /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