Skip to content

Commit c0f8599

Browse files
committed
[ARM] Add support for ARM Vector Instructions for Init Undef Pass
For Vector Instructions within the ARM Architecture, certain instructions have early-clobber restraints that are defined for the instruction. However, when using the Greedy register allocator this is ignored. To get around this, we can use the Init Undef pass to assign a Pseudo instruction for the registers that are early-clobber to ensure the restraint is followed. This adds in support for this using a new Pseudo instruction, `PseudoARMInitUndef` which is used to ensure early-clobber restrains are followed. The relevant overriding functions have also been provided to ensure the architecture is supported by the pass and the required information can be passed to ensure that early-clobber restrains are respected.
1 parent 3401d16 commit c0f8599

File tree

5 files changed

+50
-0
lines changed

5 files changed

+50
-0
lines changed

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,6 +2409,9 @@ void ARMAsmPrinter::emitInstruction(const MachineInstr *MI) {
24092409
case ARM::SEH_EpilogEnd:
24102410
ATS.emitARMWinCFIEpilogEnd();
24112411
return;
2412+
2413+
case ARM::PseudoARMInitUndef:
2414+
return;
24122415
}
24132416

24142417
MCInst TmpInst;

llvm/lib/Target/ARM/ARMBaseInstrInfo.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
#ifndef LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
1414
#define LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
1515

16+
#include "ARMBaseRegisterInfo.h"
1617
#include "MCTargetDesc/ARMBaseInfo.h"
18+
#include "MCTargetDesc/ARMMCTargetDesc.h"
1719
#include "llvm/ADT/DenseMap.h"
1820
#include "llvm/ADT/SmallSet.h"
1921
#include "llvm/CodeGen/MachineBasicBlock.h"
2022
#include "llvm/CodeGen/MachineInstr.h"
2123
#include "llvm/CodeGen/MachineInstrBuilder.h"
2224
#include "llvm/CodeGen/MachineOperand.h"
25+
#include "llvm/CodeGen/MachineRegisterInfo.h"
2326
#include "llvm/CodeGen/TargetInstrInfo.h"
2427
#include "llvm/IR/IntrinsicInst.h"
2528
#include "llvm/IR/IntrinsicsARM.h"
@@ -536,6 +539,26 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {
536539

537540
std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
538541
Register Reg) const override;
542+
543+
unsigned getUndefInitOpcode(unsigned RegClassID) const override {
544+
if (RegClassID == ARM::MQPRRegClass.getID()) {
545+
return ARM::PseudoARMInitUndef;
546+
}
547+
llvm_unreachable("Unexpected register class.");
548+
}
549+
550+
const TargetRegisterClass *
551+
getVRLargestSuperClass(const TargetRegisterClass *RC) const override {
552+
if (ARM::MQPRRegClass.hasSubClassEq(RC))
553+
return &ARM::MQPRRegClass;
554+
return RC;
555+
}
556+
557+
bool isVectorRegClass(const TargetRegisterClass *RC) const override {
558+
return ARM::MQPRRegClass.hasSubClassEq(RC);
559+
}
560+
561+
unsigned getNoRegisterValue() const override { return ARM::NoRegister; }
539562
};
540563

541564
/// Get the operands corresponding to the given \p Pred value. By default, the

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6532,3 +6532,12 @@ let isPseudo = 1 in {
65326532
let isTerminator = 1 in
65336533
def SEH_EpilogEnd : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
65346534
}
6535+
6536+
6537+
//===----------------------------------------------------------------------===//
6538+
// Pseudo Instructions for use when early-clobber is defined and Greedy Register
6539+
// Allocation is used. This ensures the constraint is used properly.
6540+
//===----------------------------------------------------------------------===//
6541+
let isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
6542+
def PseudoARMInitUndef : PseudoInst<(outs MQPR:$vd), (ins), NoItinerary, []>;
6543+
}

llvm/lib/Target/ARM/ARMSubtarget.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
277277
return &InstrInfo->getRegisterInfo();
278278
}
279279

280+
bool hasVInstructions() const override {
281+
return HasMVEIntegerOps || HasMVEFloatOps;
282+
}
283+
280284
const CallLowering *getCallLowering() const override;
281285
InstructionSelector *getInstructionSelector() const override;
282286
const LegalizerInfo *getLegalizerInfo() const override;

llvm/test/CodeGen/Thumb2/mve-intrinsics/vcaddq.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,17 @@ entry:
699699
ret <4 x i32> %0
700700
}
701701

702+
define arm_aapcs_vfpcc <4 x i32> @test_vhcaddq_rot270_s32_undef() {
703+
; CHECK-LABEL: test_vhcaddq_rot270_s32_undef:
704+
; CHECK: @ %bb.0: @ %entry
705+
; CHECK-NEXT: vhcadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #270
706+
; CHECK-NOT: vhcadd.s32 q[[REG:[0-9]+]], q{{[0-9]+}}, q[[REG]], #270
707+
; CHECK-NEXT: bx lr
708+
entry:
709+
%0 = tail call <4 x i32> @llvm.arm.mve.vcaddq.v4i32(i32 0, i32 1, <4 x i32> undef, <4 x i32> undef)
710+
ret <4 x i32> %0
711+
}
712+
702713
define arm_aapcs_vfpcc <16 x i8> @test_vhcaddq_rot90_x_s8(<16 x i8> %a, <16 x i8> %b, i16 zeroext %p) {
703714
; CHECK-LABEL: test_vhcaddq_rot90_x_s8:
704715
; CHECK: @ %bb.0: @ %entry

0 commit comments

Comments
 (0)