forked from OSchip/llvm-project
GlobalISel: Preserve load/store metadata in IRTranslator
This was dropping the invariant metadata on dead argument loads, so they weren't deleted. Atomics still need to be fixed the same way. Also, apparently store was never preserving dereferencable which should also be fixed.
This commit is contained in:
parent
03a592f18b
commit
0d0fce42b0
|
@ -284,6 +284,18 @@ public:
|
|||
return getPointerTy(DL);
|
||||
}
|
||||
|
||||
/// This callback is used to inspect load/store instructions and add
|
||||
/// target-specific MachineMemOperand flags to them. The default
|
||||
/// implementation does nothing.
|
||||
virtual MachineMemOperand::Flags getTargetMMOFlags(const Instruction &I) const {
|
||||
return MachineMemOperand::MONone;
|
||||
}
|
||||
|
||||
MachineMemOperand::Flags getLoadMemOperandFlags(const LoadInst &LI,
|
||||
const DataLayout &DL) const;
|
||||
MachineMemOperand::Flags getStoreMemOperandFlags(const StoreInst &SI,
|
||||
const DataLayout &DL) const;
|
||||
|
||||
virtual bool isSelectSupported(SelectSupportKind /*kind*/) const {
|
||||
return true;
|
||||
}
|
||||
|
@ -3763,13 +3775,6 @@ public:
|
|||
return Chain;
|
||||
}
|
||||
|
||||
/// This callback is used to inspect load/store instructions and add
|
||||
/// target-specific MachineMemOperand flags to them. The default
|
||||
/// implementation does nothing.
|
||||
virtual MachineMemOperand::Flags getMMOFlags(const Instruction &I) const {
|
||||
return MachineMemOperand::MONone;
|
||||
}
|
||||
|
||||
/// Should SelectionDAG lower an atomic store of the given kind as a normal
|
||||
/// StoreSDNode (as opposed to an AtomicSDNode)? NOTE: The intention is to
|
||||
/// eventually migrate all targets to the using StoreSDNodes, but porting is
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
|
@ -858,11 +859,6 @@ static bool isSwiftError(const Value *V) {
|
|||
|
||||
bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
|
||||
const LoadInst &LI = cast<LoadInst>(U);
|
||||
|
||||
auto Flags = LI.isVolatile() ? MachineMemOperand::MOVolatile
|
||||
: MachineMemOperand::MONone;
|
||||
Flags |= MachineMemOperand::MOLoad;
|
||||
|
||||
if (DL->getTypeStoreSize(LI.getType()) == 0)
|
||||
return true;
|
||||
|
||||
|
@ -881,6 +877,9 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto &TLI = *MF->getSubtarget().getTargetLowering();
|
||||
MachineMemOperand::Flags Flags = TLI.getLoadMemOperandFlags(LI, *DL);
|
||||
|
||||
const MDNode *Ranges =
|
||||
Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
|
||||
for (unsigned i = 0; i < Regs.size(); ++i) {
|
||||
|
@ -903,10 +902,6 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
|
|||
|
||||
bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
|
||||
const StoreInst &SI = cast<StoreInst>(U);
|
||||
auto Flags = SI.isVolatile() ? MachineMemOperand::MOVolatile
|
||||
: MachineMemOperand::MONone;
|
||||
Flags |= MachineMemOperand::MOStore;
|
||||
|
||||
if (DL->getTypeStoreSize(SI.getValueOperand()->getType()) == 0)
|
||||
return true;
|
||||
|
||||
|
@ -926,6 +921,9 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto &TLI = *MF->getSubtarget().getTargetLowering();
|
||||
MachineMemOperand::Flags Flags = TLI.getStoreMemOperandFlags(SI, *DL);
|
||||
|
||||
for (unsigned i = 0; i < Vals.size(); ++i) {
|
||||
Register Addr;
|
||||
MIRBuilder.materializePtrAdd(Addr, Base, OffsetTy, Offsets[i] / 8);
|
||||
|
|
|
@ -4057,12 +4057,6 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
|||
SDValue Ptr = getValue(SV);
|
||||
|
||||
Type *Ty = I.getType();
|
||||
|
||||
bool isVolatile = I.isVolatile();
|
||||
bool isNonTemporal = I.hasMetadata(LLVMContext::MD_nontemporal);
|
||||
bool isInvariant = I.hasMetadata(LLVMContext::MD_invariant_load);
|
||||
bool isDereferenceable =
|
||||
isDereferenceablePointer(SV, I.getType(), DAG.getDataLayout());
|
||||
unsigned Alignment = I.getAlignment();
|
||||
|
||||
AAMDNodes AAInfo;
|
||||
|
@ -4076,6 +4070,8 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
|||
if (NumValues == 0)
|
||||
return;
|
||||
|
||||
bool isVolatile = I.isVolatile();
|
||||
|
||||
SDValue Root;
|
||||
bool ConstantMemory = false;
|
||||
if (isVolatile)
|
||||
|
@ -4109,6 +4105,10 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
|||
SmallVector<SDValue, 4> Values(NumValues);
|
||||
SmallVector<SDValue, 4> Chains(std::min(MaxParallelChains, NumValues));
|
||||
EVT PtrVT = Ptr.getValueType();
|
||||
|
||||
MachineMemOperand::Flags MMOFlags
|
||||
= TLI.getLoadMemOperandFlags(I, DAG.getDataLayout());
|
||||
|
||||
unsigned ChainI = 0;
|
||||
for (unsigned i = 0; i != NumValues; ++i, ++ChainI) {
|
||||
// Serializing loads here may result in excessive register pressure, and
|
||||
|
@ -4128,16 +4128,6 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
|||
PtrVT, Ptr,
|
||||
DAG.getConstant(Offsets[i], dl, PtrVT),
|
||||
Flags);
|
||||
auto MMOFlags = MachineMemOperand::MONone;
|
||||
if (isVolatile)
|
||||
MMOFlags |= MachineMemOperand::MOVolatile;
|
||||
if (isNonTemporal)
|
||||
MMOFlags |= MachineMemOperand::MONonTemporal;
|
||||
if (isInvariant)
|
||||
MMOFlags |= MachineMemOperand::MOInvariant;
|
||||
if (isDereferenceable)
|
||||
MMOFlags |= MachineMemOperand::MODereferenceable;
|
||||
MMOFlags |= TLI.getMMOFlags(I);
|
||||
|
||||
SDValue L = DAG.getLoad(MemVTs[i], dl, Root, A,
|
||||
MachinePointerInfo(SV, Offsets[i]), Alignment,
|
||||
|
@ -4264,12 +4254,7 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
|
|||
AAMDNodes AAInfo;
|
||||
I.getAAMetadata(AAInfo);
|
||||
|
||||
auto MMOFlags = MachineMemOperand::MONone;
|
||||
if (I.isVolatile())
|
||||
MMOFlags |= MachineMemOperand::MOVolatile;
|
||||
if (I.hasMetadata(LLVMContext::MD_nontemporal))
|
||||
MMOFlags |= MachineMemOperand::MONonTemporal;
|
||||
MMOFlags |= TLI.getMMOFlags(I);
|
||||
auto MMOFlags = TLI.getStoreMemOperandFlags(I, DAG.getDataLayout());
|
||||
|
||||
// An aggregate load cannot wrap around the address space, so offsets to its
|
||||
// parts don't wrap either.
|
||||
|
@ -4638,7 +4623,7 @@ void SelectionDAGBuilder::visitAtomicCmpXchg(const AtomicCmpXchgInst &I) {
|
|||
auto Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore;
|
||||
if (I.isVolatile())
|
||||
Flags |= MachineMemOperand::MOVolatile;
|
||||
Flags |= DAG.getTargetLoweringInfo().getMMOFlags(I);
|
||||
Flags |= DAG.getTargetLoweringInfo().getTargetMMOFlags(I);
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineMemOperand *MMO =
|
||||
|
@ -4689,7 +4674,7 @@ void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) {
|
|||
auto Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore;
|
||||
if (I.isVolatile())
|
||||
Flags |= MachineMemOperand::MOVolatile;
|
||||
Flags |= DAG.getTargetLoweringInfo().getMMOFlags(I);
|
||||
Flags |= DAG.getTargetLoweringInfo().getTargetMMOFlags(I);
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineMemOperand *MMO =
|
||||
|
@ -4735,16 +4720,7 @@ void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
|
|||
I.getAlignment() < MemVT.getSizeInBits() / 8)
|
||||
report_fatal_error("Cannot generate unaligned atomic load");
|
||||
|
||||
auto Flags = MachineMemOperand::MOLoad;
|
||||
if (I.isVolatile())
|
||||
Flags |= MachineMemOperand::MOVolatile;
|
||||
if (I.hasMetadata(LLVMContext::MD_invariant_load))
|
||||
Flags |= MachineMemOperand::MOInvariant;
|
||||
if (isDereferenceablePointer(I.getPointerOperand(), I.getType(),
|
||||
DAG.getDataLayout()))
|
||||
Flags |= MachineMemOperand::MODereferenceable;
|
||||
|
||||
Flags |= TLI.getMMOFlags(I);
|
||||
auto Flags = TLI.getLoadMemOperandFlags(I, DAG.getDataLayout());
|
||||
|
||||
MachineMemOperand *MMO =
|
||||
DAG.getMachineFunction().
|
||||
|
@ -4800,10 +4776,7 @@ void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
|
|||
if (I.getAlignment() < MemVT.getSizeInBits() / 8)
|
||||
report_fatal_error("Cannot generate unaligned atomic store");
|
||||
|
||||
auto Flags = MachineMemOperand::MOStore;
|
||||
if (I.isVolatile())
|
||||
Flags |= MachineMemOperand::MOVolatile;
|
||||
Flags |= TLI.getMMOFlags(I);
|
||||
auto Flags = TLI.getStoreMemOperandFlags(I, DAG.getDataLayout());
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineMemOperand *MMO =
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
|
@ -2005,3 +2006,39 @@ int TargetLoweringBase::getDivRefinementSteps(EVT VT,
|
|||
void TargetLoweringBase::finalizeLowering(MachineFunction &MF) const {
|
||||
MF.getRegInfo().freezeReservedRegs(MF);
|
||||
}
|
||||
|
||||
MachineMemOperand::Flags
|
||||
TargetLoweringBase::getLoadMemOperandFlags(const LoadInst &LI,
|
||||
const DataLayout &DL) const {
|
||||
MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad;
|
||||
if (LI.isVolatile())
|
||||
Flags |= MachineMemOperand::MOVolatile;
|
||||
|
||||
if (LI.hasMetadata(LLVMContext::MD_nontemporal))
|
||||
Flags |= MachineMemOperand::MONonTemporal;
|
||||
|
||||
if (LI.hasMetadata(LLVMContext::MD_invariant_load))
|
||||
Flags |= MachineMemOperand::MOInvariant;
|
||||
|
||||
if (isDereferenceablePointer(LI.getPointerOperand(), LI.getType(), DL))
|
||||
Flags |= MachineMemOperand::MODereferenceable;
|
||||
|
||||
Flags |= getTargetMMOFlags(LI);
|
||||
return Flags;
|
||||
}
|
||||
|
||||
MachineMemOperand::Flags
|
||||
TargetLoweringBase::getStoreMemOperandFlags(const StoreInst &SI,
|
||||
const DataLayout &DL) const {
|
||||
MachineMemOperand::Flags Flags = MachineMemOperand::MOStore;
|
||||
|
||||
if (SI.isVolatile())
|
||||
Flags |= MachineMemOperand::MOVolatile;
|
||||
|
||||
if (SI.hasMetadata(LLVMContext::MD_nontemporal))
|
||||
Flags |= MachineMemOperand::MONonTemporal;
|
||||
|
||||
// FIXME: Not preserving dereferenceable
|
||||
Flags |= getTargetMMOFlags(SI);
|
||||
return Flags;
|
||||
}
|
||||
|
|
|
@ -9015,7 +9015,7 @@ AArch64TargetLowering::getNumInterleavedAccesses(VectorType *VecTy,
|
|||
}
|
||||
|
||||
MachineMemOperand::Flags
|
||||
AArch64TargetLowering::getMMOFlags(const Instruction &I) const {
|
||||
AArch64TargetLowering::getTargetMMOFlags(const Instruction &I) const {
|
||||
if (Subtarget->getProcFamily() == AArch64Subtarget::Falkor &&
|
||||
I.getMetadata(FALKOR_STRIDED_ACCESS_MD) != nullptr)
|
||||
return MOStridedAccess;
|
||||
|
|
|
@ -611,7 +611,8 @@ public:
|
|||
unsigned getNumInterleavedAccesses(VectorType *VecTy,
|
||||
const DataLayout &DL) const;
|
||||
|
||||
MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override;
|
||||
MachineMemOperand::Flags getTargetMMOFlags(
|
||||
const Instruction &I) const override;
|
||||
|
||||
bool functionArgumentNeedsConsecutiveRegisters(Type *Ty,
|
||||
CallingConv::ID CallConv,
|
||||
|
|
|
@ -3995,7 +3995,7 @@ SDValue SystemZTargetLowering::lowerATOMIC_CMP_SWAP(SDValue Op,
|
|||
}
|
||||
|
||||
MachineMemOperand::Flags
|
||||
SystemZTargetLowering::getMMOFlags(const Instruction &I) const {
|
||||
SystemZTargetLowering::getTargetMMOFlags(const Instruction &I) const {
|
||||
// Because of how we convert atomic_load and atomic_store to normal loads and
|
||||
// stores in the DAG, we need to ensure that the MMOs are marked volatile
|
||||
// since DAGCombine hasn't been updated to account for atomic, but non
|
||||
|
|
|
@ -677,7 +677,8 @@ private:
|
|||
MachineBasicBlock *MBB,
|
||||
unsigned Opcode) const;
|
||||
|
||||
MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override;
|
||||
MachineMemOperand::Flags
|
||||
getTargetMMOFlags(const Instruction &I) const override;
|
||||
const TargetRegisterClass *getRepRegClassFor(MVT VT) const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -996,7 +996,7 @@ LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const {
|
|||
}
|
||||
|
||||
MachineMemOperand::Flags
|
||||
XCoreTargetLowering::getMMOFlags(const Instruction &I) const {
|
||||
XCoreTargetLowering::getTargetMMOFlags(const Instruction &I) const {
|
||||
// Because of how we convert atomic_load and atomic_store to normal loads and
|
||||
// stores in the DAG, we need to ensure that the MMOs are marked volatile
|
||||
// since DAGCombine hasn't been updated to account for atomic, but non
|
||||
|
|
|
@ -188,7 +188,8 @@ namespace llvm {
|
|||
SDValue LowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override;
|
||||
MachineMemOperand::Flags getTargetMMOFlags(
|
||||
const Instruction &I) const override;
|
||||
|
||||
// Inline asm support
|
||||
std::pair<unsigned, const TargetRegisterClass *>
|
||||
|
|
|
@ -18,7 +18,7 @@ define i32 @main() #0 !dbg !14 {
|
|||
; CHECK: [[GV1:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var2, debug-location !DILocation(line: 0, scope: !22)
|
||||
; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.retval
|
||||
; CHECK: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %ir.retval)
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0), debug-location !17 :: (load 4 from @var1)
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0), debug-location !17 :: (dereferenceable load 4 from @var1)
|
||||
; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LOAD]](s32), [[C1]], debug-location !19
|
||||
; CHECK: G_BRCOND [[ICMP]](s1), %bb.2, debug-location !20
|
||||
; CHECK: G_BR %bb.3, debug-location !20
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
; RUN: llc -mtriple=aarch64-- -mcpu=falkor -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - | FileCheck %s
|
||||
|
||||
define i32 @load_invariant(i32* %ptr) {
|
||||
; CHECK-LABEL: name: load_invariant
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (invariant load 4 from %ir.ptr)
|
||||
; CHECK: $w0 = COPY [[LOAD]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%load = load i32, i32* %ptr, align 4, !invariant.load !0
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @load_volatile_invariant(i32* %ptr) {
|
||||
; CHECK-LABEL: name: load_volatile_invariant
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (volatile invariant load 4 from %ir.ptr)
|
||||
; CHECK: $w0 = COPY [[LOAD]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%load = load volatile i32, i32* %ptr, align 4, !invariant.load !0
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @load_dereferenceable(i32* dereferenceable(4) %ptr) {
|
||||
; CHECK-LABEL: name: load_dereferenceable
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (dereferenceable load 4 from %ir.ptr)
|
||||
; CHECK: $w0 = COPY [[LOAD]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%load = load i32, i32* %ptr, align 4
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @load_dereferenceable_invariant(i32* dereferenceable(4) %ptr) {
|
||||
; CHECK-LABEL: name: load_dereferenceable_invariant
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (dereferenceable invariant load 4 from %ir.ptr)
|
||||
; CHECK: $w0 = COPY [[LOAD]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%load = load i32, i32* %ptr, align 4, !invariant.load !0
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @load_nontemporal(i32* %ptr) {
|
||||
; CHECK-LABEL: name: load_nontemporal
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (non-temporal load 4 from %ir.ptr)
|
||||
; CHECK: $w0 = COPY [[LOAD]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%load = load i32, i32* %ptr, align 4, !nontemporal !0
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @load_falkor_strided_access(i32* %ptr) {
|
||||
; CHECK-LABEL: name: load_falkor_strided_access
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: ("aarch64-strided-access" load 4 from %ir.ptr)
|
||||
; CHECK: $w0 = COPY [[LOAD]](s32)
|
||||
; CHECK: RET_ReallyLR implicit $w0
|
||||
%load = load i32, i32* %ptr, align 4, !falkor.strided.access !0
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
!0 = !{}
|
|
@ -32,7 +32,7 @@ define void @foo() ssp {
|
|||
; CHECK-MIR-NEXT: G_STORE %2(p0), %0(p0) :: (volatile store 8 into %stack.0.StackGuardSlot)
|
||||
; CHECK-MIR-NEXT: %3:_(p0) = G_FRAME_INDEX %stack.1.buf
|
||||
; CHECK-MIR-NEXT: %4:gpr64sp(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load 8 from @__stack_chk_guard)
|
||||
; CHECK-MIR-NEXT: %5:_(p0) = G_LOAD %0(p0) :: (volatile load 8 from %ir.StackGuardSlot)
|
||||
; CHECK-MIR-NEXT: %5:_(p0) = G_LOAD %0(p0) :: (volatile dereferenceable load 8 from %ir.StackGuardSlot)
|
||||
; CHECK-MIR-NEXT: %6:_(s1) = G_ICMP intpred(eq), %4(p0), %5
|
||||
; CHECK-MIR-NEXT: G_BRCOND %6(s1), %bb.2
|
||||
; CHECK-MIR-NEXT: G_BR %bb.3
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
; RUN: llc -mtriple=aarch64-- -mcpu=falkor -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - | FileCheck %s
|
||||
|
||||
define void @store_nontemporal(i32* dereferenceable(4) %ptr) {
|
||||
; CHECK-LABEL: name: store_nontemporal
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
|
||||
; CHECK: G_STORE [[C]](s32), [[COPY]](p0) :: (non-temporal store 4 into %ir.ptr)
|
||||
; CHECK: RET_ReallyLR
|
||||
store i32 0, i32* %ptr, align 4, !nontemporal !0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store_dereferenceable(i32* dereferenceable(4) %ptr) {
|
||||
; CHECK-LABEL: name: store_dereferenceable
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
|
||||
; CHECK: G_STORE [[C]](s32), [[COPY]](p0) :: (store 4 into %ir.ptr)
|
||||
; CHECK: RET_ReallyLR
|
||||
store i32 0, i32* %ptr, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store_volatile_dereferenceable(i32* dereferenceable(4) %ptr) {
|
||||
; CHECK-LABEL: name: store_volatile_dereferenceable
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
|
||||
; CHECK: G_STORE [[C]](s32), [[COPY]](p0) :: (volatile store 4 into %ir.ptr)
|
||||
; CHECK: RET_ReallyLR
|
||||
store volatile i32 0, i32* %ptr, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store_falkor_strided_access(i32* %ptr) {
|
||||
; CHECK-LABEL: name: store_falkor_strided_access
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $x0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
||||
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
|
||||
; CHECK: G_STORE [[C]](s32), [[COPY]](p0) :: ("aarch64-strided-access" store 4 into %ir.ptr)
|
||||
; CHECK: RET_ReallyLR
|
||||
store i32 0, i32* %ptr, align 4, !falkor.strided.access !0
|
||||
ret void
|
||||
}
|
||||
|
||||
!0 = !{}
|
|
@ -25,7 +25,7 @@ define i32 @foo() {
|
|||
; CHECK: [[C2:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 3
|
||||
; CHECK: [[GV2:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var3
|
||||
; CHECK: [[C3:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 0
|
||||
; CHECK: [[LOAD:%[0-9]+]]:gpr(s32) = G_LOAD [[GV]](p0) :: (load 4 from @var1)
|
||||
; CHECK: [[LOAD:%[0-9]+]]:gpr(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @var1)
|
||||
; CHECK: [[ICMP:%[0-9]+]]:gpr(s32) = G_ICMP intpred(ne), [[LOAD]](s32), [[C]]
|
||||
; CHECK: [[TRUNC:%[0-9]+]]:gpr(s1) = G_TRUNC [[ICMP]](s32)
|
||||
; CHECK: G_BRCOND [[TRUNC]](s1), %bb.3
|
||||
|
|
|
@ -1364,10 +1364,10 @@ define void @void_func_byval_struct_i8_i32({ i8, i32 } addrspace(5)* byval %arg0
|
|||
; CHECK: [[LOAD:%[0-9]+]]:_(p5) = G_LOAD [[FRAME_INDEX]](p5) :: (invariant load 4 from %fixed-stack.0, align 1, addrspace 5)
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr_64 = COPY $sgpr30_sgpr31
|
||||
; CHECK: [[DEF:%[0-9]+]]:_(p1) = G_IMPLICIT_DEF
|
||||
; CHECK: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[LOAD]](p5) :: (load 1 from %ir.arg0, align 4, addrspace 5)
|
||||
; CHECK: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[LOAD]](p5) :: (dereferenceable load 1 from %ir.arg0, align 4, addrspace 5)
|
||||
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
|
||||
; CHECK: [[PTR_ADD:%[0-9]+]]:_(p5) = G_PTR_ADD [[LOAD]], [[C]](s32)
|
||||
; CHECK: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p5) :: (load 4 from %ir.arg0 + 4, addrspace 5)
|
||||
; CHECK: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p5) :: (dereferenceable load 4 from %ir.arg0 + 4, addrspace 5)
|
||||
; CHECK: G_STORE [[LOAD1]](s8), [[DEF]](p1) :: (store 1 into `{ i8, i32 } addrspace(1)* undef`, align 4, addrspace 1)
|
||||
; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
|
||||
; CHECK: [[PTR_ADD1:%[0-9]+]]:_(p1) = G_PTR_ADD [[DEF]], [[C1]](s64)
|
||||
|
@ -1391,13 +1391,13 @@ define void @void_func_byval_struct_i8_i32_x2({ i8, i32 } addrspace(5)* byval %a
|
|||
; CHECK: [[COPY1:%[0-9]+]]:sgpr_64 = COPY $sgpr30_sgpr31
|
||||
; CHECK: [[DEF:%[0-9]+]]:_(p1) = G_IMPLICIT_DEF
|
||||
; CHECK: [[DEF1:%[0-9]+]]:_(p3) = G_IMPLICIT_DEF
|
||||
; CHECK: [[LOAD2:%[0-9]+]]:_(s8) = G_LOAD [[LOAD]](p5) :: (volatile load 1 from %ir.arg0, align 4, addrspace 5)
|
||||
; CHECK: [[LOAD2:%[0-9]+]]:_(s8) = G_LOAD [[LOAD]](p5) :: (volatile dereferenceable load 1 from %ir.arg0, align 4, addrspace 5)
|
||||
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
|
||||
; CHECK: [[PTR_ADD:%[0-9]+]]:_(p5) = G_PTR_ADD [[LOAD]], [[C]](s32)
|
||||
; CHECK: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p5) :: (volatile load 4 from %ir.arg0 + 4, addrspace 5)
|
||||
; CHECK: [[LOAD4:%[0-9]+]]:_(s8) = G_LOAD [[LOAD1]](p5) :: (volatile load 1 from %ir.arg1, align 4, addrspace 5)
|
||||
; CHECK: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p5) :: (volatile dereferenceable load 4 from %ir.arg0 + 4, addrspace 5)
|
||||
; CHECK: [[LOAD4:%[0-9]+]]:_(s8) = G_LOAD [[LOAD1]](p5) :: (volatile dereferenceable load 1 from %ir.arg1, align 4, addrspace 5)
|
||||
; CHECK: [[PTR_ADD1:%[0-9]+]]:_(p5) = G_PTR_ADD [[LOAD1]], [[C]](s32)
|
||||
; CHECK: [[LOAD5:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD1]](p5) :: (volatile load 4 from %ir.arg1 + 4, addrspace 5)
|
||||
; CHECK: [[LOAD5:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD1]](p5) :: (volatile dereferenceable load 4 from %ir.arg1 + 4, addrspace 5)
|
||||
; CHECK: G_STORE [[LOAD2]](s8), [[DEF]](p1) :: (volatile store 1 into `{ i8, i32 } addrspace(1)* undef`, align 4, addrspace 1)
|
||||
; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
|
||||
; CHECK: [[PTR_ADD2:%[0-9]+]]:_(p1) = G_PTR_ADD [[DEF]], [[C1]](s64)
|
||||
|
@ -1427,8 +1427,8 @@ define void @void_func_byval_i32_byval_i64(i32 addrspace(5)* byval %arg0, i64 ad
|
|||
; CHECK: [[COPY:%[0-9]+]]:sgpr_64 = COPY $sgpr30_sgpr31
|
||||
; CHECK: [[DEF:%[0-9]+]]:_(p1) = G_IMPLICIT_DEF
|
||||
; CHECK: [[DEF1:%[0-9]+]]:_(p1) = G_IMPLICIT_DEF
|
||||
; CHECK: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[LOAD]](p5) :: (load 4 from %ir.arg0, addrspace 5)
|
||||
; CHECK: [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[LOAD1]](p5) :: (load 8 from %ir.arg1, addrspace 5)
|
||||
; CHECK: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[LOAD]](p5) :: (dereferenceable load 4 from %ir.arg0, addrspace 5)
|
||||
; CHECK: [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[LOAD1]](p5) :: (dereferenceable load 8 from %ir.arg1, addrspace 5)
|
||||
; CHECK: G_STORE [[LOAD2]](s32), [[DEF]](p1) :: (store 4 into `i32 addrspace(1)* undef`, addrspace 1)
|
||||
; CHECK: G_STORE [[LOAD3]](s64), [[DEF1]](p1) :: (store 8 into `i64 addrspace(1)* undef`, addrspace 1)
|
||||
; CHECK: [[COPY1:%[0-9]+]]:ccr_sgpr_64 = COPY [[COPY]]
|
||||
|
|
|
@ -29,13 +29,13 @@ define void @testVaCopyArg(i8* %fmt, ...) {
|
|||
; MIPS32: G_STORE [[COPY]](p0), [[FRAME_INDEX3]](p0) :: (store 4 into %ir.fmt.addr)
|
||||
; MIPS32: G_VASTART [[FRAME_INDEX4]](p0) :: (store 4 into %ir.ap1, align 1)
|
||||
; MIPS32: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.va_copy), [[FRAME_INDEX5]](p0), [[FRAME_INDEX4]](p0)
|
||||
; MIPS32: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load 4 from %ir.aq)
|
||||
; MIPS32: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (dereferenceable load 4 from %ir.aq)
|
||||
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
|
||||
; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
|
||||
; MIPS32: G_STORE [[GEP]](p0), [[FRAME_INDEX5]](p0) :: (store 4 into %ir.aq)
|
||||
; MIPS32: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
|
||||
; MIPS32: G_STORE [[PTR_ADD]](p0), [[FRAME_INDEX5]](p0) :: (store 4 into %ir.aq)
|
||||
; MIPS32: [[LOAD1:%[0-9]+]]:_(p0) = G_LOAD [[LOAD]](p0) :: (load 4 from %ir.2)
|
||||
; MIPS32: G_STORE [[LOAD1]](p0), [[FRAME_INDEX6]](p0) :: (store 4 into %ir.s)
|
||||
; MIPS32: [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load 4 from %ir.s)
|
||||
; MIPS32: [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (dereferenceable load 4 from %ir.s)
|
||||
; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
|
||||
; MIPS32: $a0 = COPY [[COPY4]](p0)
|
||||
; MIPS32: $a1 = COPY [[LOAD2]](p0)
|
||||
|
|
|
@ -20,7 +20,7 @@ define float @test_return_f1(float %f.coerce) {
|
|||
; ALL: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.f
|
||||
; ALL: G_STORE [[TRUNC]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %ir.coerce.dive2)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %ir.coerce.dive13)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 4 from %ir.coerce.dive13)
|
||||
; ALL: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[LOAD]](s32)
|
||||
; ALL: $xmm0 = COPY [[ANYEXT]](s128)
|
||||
; ALL: RET 0, implicit $xmm0
|
||||
|
@ -50,7 +50,7 @@ define double @test_return_d1(double %d.coerce) {
|
|||
; ALL: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.d
|
||||
; ALL: G_STORE [[TRUNC]](s64), [[FRAME_INDEX1]](p0) :: (store 8 into %ir.coerce.dive2)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.0, align 8), (load 1 from %ir.1, align 8)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load 8 from %ir.coerce.dive13)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 8 from %ir.coerce.dive13)
|
||||
; ALL: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[LOAD]](s64)
|
||||
; ALL: $xmm0 = COPY [[ANYEXT]](s128)
|
||||
; ALL: RET 0, implicit $xmm0
|
||||
|
@ -80,12 +80,12 @@ define { double, double } @test_return_d2(double %d.coerce0, double %d.coerce1)
|
|||
; ALL: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.d
|
||||
; ALL: G_STORE [[TRUNC]](s64), [[FRAME_INDEX1]](p0) :: (store 8 into %ir.1)
|
||||
; ALL: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
|
||||
; ALL: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX1]], [[C1]](s64)
|
||||
; ALL: G_STORE [[TRUNC1]](s64), [[GEP]](p0) :: (store 8 into %ir.2)
|
||||
; ALL: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX1]], [[C1]](s64)
|
||||
; ALL: G_STORE [[TRUNC1]](s64), [[PTR_ADD]](p0) :: (store 8 into %ir.2)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.3, align 8), (load 1 from %ir.4, align 8)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load 8 from %ir.5)
|
||||
; ALL: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX]], [[C1]](s64)
|
||||
; ALL: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[GEP1]](p0) :: (load 8 from %ir.5 + 8)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 8 from %ir.5)
|
||||
; ALL: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX]], [[C1]](s64)
|
||||
; ALL: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD1]](p0) :: (dereferenceable load 8 from %ir.5 + 8)
|
||||
; ALL: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[LOAD]](s64)
|
||||
; ALL: $xmm0 = COPY [[ANYEXT]](s128)
|
||||
; ALL: [[ANYEXT1:%[0-9]+]]:_(s128) = G_ANYEXT [[LOAD1]](s64)
|
||||
|
@ -117,7 +117,7 @@ define i32 @test_return_i1(i32 %i.coerce) {
|
|||
; ALL: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.i
|
||||
; ALL: G_STORE [[COPY]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %ir.coerce.dive2)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %ir.coerce.dive13)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 4 from %ir.coerce.dive13)
|
||||
; ALL: $eax = COPY [[LOAD]](s32)
|
||||
; ALL: RET 0, implicit $eax
|
||||
entry:
|
||||
|
@ -143,7 +143,7 @@ define i64 @test_return_i2(i64 %i.coerce) {
|
|||
; ALL: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.i
|
||||
; ALL: G_STORE [[COPY]](s64), [[FRAME_INDEX1]](p0) :: (store 8 into %ir.0, align 4)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.1, align 4), (load 1 from %ir.2, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load 8 from %ir.3, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 8 from %ir.3, align 4)
|
||||
; ALL: $rax = COPY [[LOAD]](s64)
|
||||
; ALL: RET 0, implicit $rax
|
||||
entry:
|
||||
|
@ -172,14 +172,14 @@ define { i64, i32 } @test_return_i3(i64 %i.coerce0, i32 %i.coerce1) {
|
|||
; ALL: [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3.tmp
|
||||
; ALL: G_STORE [[COPY]](s64), [[FRAME_INDEX2]](p0) :: (store 8 into %ir.0, align 4)
|
||||
; ALL: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
|
||||
; ALL: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX2]], [[C1]](s64)
|
||||
; ALL: G_STORE [[COPY1]](s32), [[GEP]](p0) :: (store 4 into %ir.1)
|
||||
; ALL: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX2]], [[C1]](s64)
|
||||
; ALL: G_STORE [[COPY1]](s32), [[PTR_ADD]](p0) :: (store 4 into %ir.1)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX1]](p0), [[FRAME_INDEX2]](p0), [[C]](s64), 0 :: (store 1 into %ir.2, align 4), (load 1 from %ir.3, align 4)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.4, align 4), (load 1 from %ir.5, align 4)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX3]](p0), [[FRAME_INDEX]](p0), [[C]](s64), 0 :: (store 1 into %ir.6, align 8), (load 1 from %ir.7, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX3]](p0) :: (load 8 from %ir.tmp)
|
||||
; ALL: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX3]], [[C1]](s64)
|
||||
; ALL: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.tmp + 8, align 8)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX3]](p0) :: (dereferenceable load 8 from %ir.tmp)
|
||||
; ALL: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX3]], [[C1]](s64)
|
||||
; ALL: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD1]](p0) :: (dereferenceable load 4 from %ir.tmp + 8, align 8)
|
||||
; ALL: $rax = COPY [[LOAD]](s64)
|
||||
; ALL: $edx = COPY [[LOAD1]](s32)
|
||||
; ALL: RET 0, implicit $rax, implicit $edx
|
||||
|
@ -216,12 +216,12 @@ define { i64, i64 } @test_return_i4(i64 %i.coerce0, i64 %i.coerce1) {
|
|||
; ALL: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.i
|
||||
; ALL: G_STORE [[COPY]](s64), [[FRAME_INDEX1]](p0) :: (store 8 into %ir.1, align 4)
|
||||
; ALL: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
|
||||
; ALL: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX1]], [[C1]](s64)
|
||||
; ALL: G_STORE [[COPY1]](s64), [[GEP]](p0) :: (store 8 into %ir.2, align 4)
|
||||
; ALL: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX1]], [[C1]](s64)
|
||||
; ALL: G_STORE [[COPY1]](s64), [[PTR_ADD]](p0) :: (store 8 into %ir.2, align 4)
|
||||
; ALL: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[FRAME_INDEX]](p0), [[FRAME_INDEX1]](p0), [[C]](s64), 0 :: (store 1 into %ir.3, align 4), (load 1 from %ir.4, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load 8 from %ir.5, align 4)
|
||||
; ALL: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX]], [[C1]](s64)
|
||||
; ALL: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[GEP1]](p0) :: (load 8 from %ir.5 + 8, align 4)
|
||||
; ALL: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 8 from %ir.5, align 4)
|
||||
; ALL: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX]], [[C1]](s64)
|
||||
; ALL: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD1]](p0) :: (dereferenceable load 8 from %ir.5 + 8, align 4)
|
||||
; ALL: $rax = COPY [[LOAD]](s64)
|
||||
; ALL: $rdx = COPY [[LOAD1]](s64)
|
||||
; ALL: RET 0, implicit $rax, implicit $rdx
|
||||
|
|
Loading…
Reference in New Issue