class MachineOperand;
class GISelKnownBits;
class MachineDominatorTree;
+class LegalizerInfo;
struct PreferredTuple {
LLT Ty; // The result type of the extend.
GISelChangeObserver &Observer;
GISelKnownBits *KB;
MachineDominatorTree *MDT;
+ const LegalizerInfo *LI;
public:
CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
GISelKnownBits *KB = nullptr,
- MachineDominatorTree *MDT = nullptr);
+ MachineDominatorTree *MDT = nullptr,
+ const LegalizerInfo *LI = nullptr);
GISelKnownBits *getKnownBits() const {
return KB;
#include "llvm/CodeGen/GlobalISel/Combiner.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
CombinerHelper::CombinerHelper(GISelChangeObserver &Observer,
MachineIRBuilder &B, GISelKnownBits *KB,
- MachineDominatorTree *MDT)
+ MachineDominatorTree *MDT,
+ const LegalizerInfo *LI)
: Builder(B), MRI(Builder.getMF().getRegInfo()), Observer(Observer),
- KB(KB), MDT(MDT) {
+ KB(KB), MDT(MDT), LI(LI) {
(void)this->KB;
}
for (auto &UseMI : MRI.use_nodbg_instructions(LoadValue.getReg())) {
if (UseMI.getOpcode() == TargetOpcode::G_SEXT ||
UseMI.getOpcode() == TargetOpcode::G_ZEXT ||
- UseMI.getOpcode() == TargetOpcode::G_ANYEXT) {
+ (UseMI.getOpcode() == TargetOpcode::G_ANYEXT)) {
+ // Check for legality.
+ if (LI) {
+ LegalityQuery::MemDesc MMDesc;
+ const auto &MMO = **MI.memoperands_begin();
+ MMDesc.SizeInBits = MMO.getSizeInBits();
+ MMDesc.AlignInBits = MMO.getAlign().value() * 8;
+ MMDesc.Ordering = MMO.getOrdering();
+ LLT UseTy = MRI.getType(UseMI.getOperand(0).getReg());
+ LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
+ if (LI->getAction({MI.getOpcode(), {UseTy, SrcTy}, {MMDesc}}).Action !=
+ LegalizeActions::Legal)
+ continue;
+ }
Preferred = ChoosePreferredUse(Preferred,
MRI.getType(UseMI.getOperand(0).getReg()),
UseMI.getOpcode(), &UseMI);
let DisableRuleOption = "aarch64prelegalizercombiner-disable-rule";
}
-def AArch64PostLegalizerCombinerHelper: GICombinerHelper<
- "AArch64GenPostLegalizerCombinerHelper", [erase_undef_store]> {
+def AArch64PostLegalizerCombinerHelper
+ : GICombinerHelper<"AArch64GenPostLegalizerCombinerHelper",
+ [erase_undef_store, combines_for_extload]> {
let DisableRuleOption = "aarch64postlegalizercombiner-disable-rule";
}
bool AArch64PostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
MachineInstr &MI,
MachineIRBuilder &B) const {
- CombinerHelper Helper(Observer, B, KB, MDT);
+ const auto *LI =
+ MI.getParent()->getParent()->getSubtarget().getLegalizerInfo();
+ CombinerHelper Helper(Observer, B, KB, MDT, LI);
return Generated.tryCombineAll(Observer, MI, B, Helper);
}
--- /dev/null
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-postlegalizer-combiner -global-isel -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+ define void @test_zeroext(i8* %addr) {
+ entry:
+ ret void
+ }
+ define void @test_no_anyext(i8* %addr) {
+ entry:
+ ret void
+ }
+...
+
+---
+name: test_zeroext
+legalized: true
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: test_zeroext
+ ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load 1 from %ir.addr)
+ ; CHECK: $w0 = COPY [[ZEXTLOAD]](s32)
+ %0:_(p0) = COPY $x0
+ %1:_(s8) = G_LOAD %0 :: (load 1 from %ir.addr)
+ %2:_(s32) = G_ZEXT %1
+ $w0 = COPY %2
+...
+
+---
+name: test_no_anyext
+legalized: true
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; Check that we don't try to do an anyext combine. We don't want to do this
+ ; because an anyexting load like s64 = G_LOAD %p (load 4) isn't legal.
+ ; CHECK-LABEL: name: test_no_anyext
+ ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load 4 from %ir.addr)
+ ; CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[LOAD]](s32)
+ ; CHECK: $x0 = COPY [[ANYEXT]](s64)
+ %0:_(p0) = COPY $x0
+ %1:_(s32) = G_LOAD %0 :: (load 4 from %ir.addr)
+ %2:_(s64) = G_ANYEXT %1
+ $x0 = COPY %2
+...