[stackmaps] Legalise patchpoint arguments.

This is similar to D125680, but for llvm.experimental.patchpoint
(instead of llvm.experimental.stackmap).

Differential review: https://reviews.llvm.org/D129268
This commit is contained in:
Edd Barrett 2022-07-15 12:00:14 +01:00
parent f8605da875
commit 2e62a26fd7
No known key found for this signature in database
11 changed files with 367 additions and 87 deletions

View File

@ -1292,6 +1292,12 @@ enum NodeType {
// Outputs: output chain, glue
STACKMAP,
// The `llvm.experimental.patchpoint.*` intrinsic.
// Operands: input chain, [glue], reg-mask, <id>, <numShadowBytes>, callee,
// <numArgs>, cc, ...
// Outputs: [rv], output chain, glue
PATCHPOINT,
// Vector Predication
#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) VPSDID,
#include "llvm/IR/VPIntrinsics.def"

View File

@ -321,7 +321,11 @@ private:
void Select_FREEZE(SDNode *N);
void Select_ARITH_FENCE(SDNode *N);
void pushStackMapLiveVariable(SmallVectorImpl<SDValue> &Ops, SDValue Operand,
SDLoc DL);
void Select_STACKMAP(SDNode *N);
void Select_PATCHPOINT(SDNode *N);
private:
void DoInstructionSelection();

View File

@ -2918,6 +2918,9 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
case ISD::STACKMAP:
Res = SoftPromoteHalfOp_STACKMAP(N, OpNo);
break;
case ISD::PATCHPOINT:
Res = SoftPromoteHalfOp_PATCHPOINT(N, OpNo);
break;
}
if (!Res.getNode())
@ -3059,3 +3062,18 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo) {
return SDValue(); // Signal that we replaced the node ourselves.
}
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_PATCHPOINT(SDNode *N,
unsigned OpNo) {
assert(OpNo >= 7);
SmallVector<SDValue> NewOps(N->ops().begin(), N->ops().end());
SDValue Op = N->getOperand(OpNo);
NewOps[OpNo] = GetSoftPromotedHalf(Op);
SDValue NewNode =
DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), NewOps);
for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
return SDValue(); // Signal that we replaced the node ourselves.
}

View File

@ -1727,6 +1727,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
case ISD::STACKMAP:
Res = PromoteIntOp_STACKMAP(N, OpNo);
break;
case ISD::PATCHPOINT:
Res = PromoteIntOp_PATCHPOINT(N, OpNo);
break;
}
// If the result is null, the sub-method took care of registering results etc.
@ -2341,6 +2344,15 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
}
SDValue DAGTypeLegalizer::PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
assert(OpNo >= 7);
SmallVector<SDValue> NewOps(N->ops().begin(), N->ops().end());
SDValue Operand = N->getOperand(OpNo);
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Operand.getValueType());
NewOps[OpNo] = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), NVT, Operand);
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
}
//===----------------------------------------------------------------------===//
// Integer Result Expansion
//===----------------------------------------------------------------------===//
@ -4693,6 +4705,9 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
case ISD::STACKMAP:
Res = ExpandIntOp_STACKMAP(N, OpNo);
break;
case ISD::PATCHPOINT:
Res = ExpandIntOp_PATCHPOINT(N, OpNo);
break;
}
// If the result is null, the sub-method took care of registering results etc.
@ -5524,30 +5539,67 @@ SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
SDValue DAGTypeLegalizer::ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
assert(OpNo > 1);
SDValue Op = N->getOperand(OpNo);
SDLoc DL = SDLoc(N);
SmallVector<SDValue> NewOps;
// FIXME: Non-constant operands are not yet handled:
// - https://github.com/llvm/llvm-project/issues/26431
// - https://github.com/llvm/llvm-project/issues/55957
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
if (!CN)
return SDValue();
// Copy operands before the one being expanded.
SmallVector<SDValue> NewOps;
for (unsigned I = 0; I < OpNo; I++)
NewOps.push_back(N->getOperand(I));
if (Op->getOpcode() == ISD::Constant) {
ConstantSDNode *CN = cast<ConstantSDNode>(Op);
EVT Ty = Op.getValueType();
if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
NewOps.push_back(
DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
} else {
// FIXME: https://github.com/llvm/llvm-project/issues/55609
return SDValue();
}
EVT Ty = Op.getValueType();
SDLoc DL = SDLoc(N);
if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
NewOps.push_back(
DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
} else {
// FIXME: Non-constant operands are not yet handled:
// - https://github.com/llvm/llvm-project/issues/26431
// - https://github.com/llvm/llvm-project/issues/55957
// FIXME: https://github.com/llvm/llvm-project/issues/55609
return SDValue();
}
// Copy remaining operands.
for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
NewOps.push_back(N->getOperand(I));
SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
return SDValue(); // Signal that we have replaced the node already.
}
SDValue DAGTypeLegalizer::ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
assert(OpNo >= 7);
SDValue Op = N->getOperand(OpNo);
// FIXME: Non-constant operands are not yet handled:
// - https://github.com/llvm/llvm-project/issues/26431
// - https://github.com/llvm/llvm-project/issues/55957
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
if (!CN)
return SDValue();
// Copy operands before the one being expanded.
SmallVector<SDValue> NewOps;
for (unsigned I = 0; I < OpNo; I++)
NewOps.push_back(N->getOperand(I));
EVT Ty = Op.getValueType();
SDLoc DL = SDLoc(N);
if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
NewOps.push_back(
DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
} else {
// FIXME: https://github.com/llvm/llvm-project/issues/55609
return SDValue();
}

View File

@ -403,6 +403,7 @@ private:
SDValue PromoteIntOp_VP_REDUCE(SDNode *N, unsigned OpNo);
SDValue PromoteIntOp_SET_ROUNDING(SDNode *N);
SDValue PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo);
SDValue PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code);
@ -495,6 +496,7 @@ private:
SDValue ExpandIntOp_ATOMIC_STORE(SDNode *N);
SDValue ExpandIntOp_SPLAT_VECTOR(SDNode *N);
SDValue ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo);
SDValue ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
ISD::CondCode &CCCode, const SDLoc &dl);
@ -744,6 +746,7 @@ private:
SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);
SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo);
SDValue SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo);
SDValue SoftPromoteHalfOp_PATCHPOINT(SDNode *N, unsigned OpNo);
//===--------------------------------------------------------------------===//
// Scalarization Support: LegalizeVectorTypes.cpp

View File

@ -9302,19 +9302,18 @@ void SelectionDAGBuilder::populateCallLoweringInfo(
static void addStackMapLiveVars(const CallBase &Call, unsigned StartIdx,
const SDLoc &DL, SmallVectorImpl<SDValue> &Ops,
SelectionDAGBuilder &Builder) {
for (unsigned i = StartIdx, e = Call.arg_size(); i != e; ++i) {
SDValue OpVal = Builder.getValue(Call.getArgOperand(i));
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(OpVal)) {
Ops.push_back(
Builder.DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
Ops.push_back(
Builder.DAG.getTargetConstant(C->getSExtValue(), DL, MVT::i64));
} else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(OpVal)) {
const TargetLowering &TLI = Builder.DAG.getTargetLoweringInfo();
Ops.push_back(Builder.DAG.getTargetFrameIndex(
FI->getIndex(), TLI.getFrameIndexTy(Builder.DAG.getDataLayout())));
} else
Ops.push_back(OpVal);
SelectionDAG &DAG = Builder.DAG;
for (unsigned I = StartIdx; I < Call.arg_size(); I++) {
SDValue Op = Builder.getValue(Call.getArgOperand(I));
// Things on the stack are pointer-typed, meaning that they are already
// legal and can be emitted directly to target nodes.
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
Ops.push_back(DAG.getTargetFrameIndex(FI->getIndex(), Op.getValueType()));
} else {
// Otherwise emit a target independent node to be legalised.
Ops.push_back(Builder.getValue(Call.getArgOperand(I)));
}
}
}
@ -9366,20 +9365,7 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) {
Ops.push_back(ShadConst);
// Add the live variables.
for (unsigned I = 2; I < CI.arg_size(); I++) {
SDValue Op = getValue(CI.getArgOperand(I));
// Things on the stack are pointer-typed, meaning that they are already
// legal and can be emitted directly to target nodes.
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
Ops.push_back(DAG.getTargetFrameIndex(
FI->getIndex(), TLI.getFrameIndexTy(DAG.getDataLayout())));
} else {
// Otherwise emit a target independent node to be legalised.
Ops.push_back(getValue(CI.getArgOperand(I)));
}
}
addStackMapLiveVars(CI, 2, DL, Ops, *this);
// Create the STACKMAP node.
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
@ -9456,6 +9442,19 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
// Replace the target specific call node with the patchable intrinsic.
SmallVector<SDValue, 8> Ops;
// Push the chain.
Ops.push_back(*(Call->op_begin()));
// Optionally, push the glue (if any).
if (HasGlue)
Ops.push_back(*(Call->op_end() - 1));
// Push the register mask info.
if (HasGlue)
Ops.push_back(*(Call->op_end() - 2));
else
Ops.push_back(*(Call->op_end() - 1));
// Add the <id> and <numBytes> constants.
SDValue IDVal = getValue(CB.getArgOperand(PatchPointOpers::IDPos));
Ops.push_back(DAG.getTargetConstant(
@ -9484,27 +9483,13 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
for (unsigned i = NumMetaOpers, e = NumMetaOpers + NumArgs; i != e; ++i)
Ops.push_back(getValue(CB.getArgOperand(i)));
// Push the arguments from the call instruction up to the register mask.
// Push the arguments from the call instruction.
SDNode::op_iterator e = HasGlue ? Call->op_end()-2 : Call->op_end()-1;
Ops.append(Call->op_begin() + 2, e);
// Push live variables for the stack map.
addStackMapLiveVars(CB, NumMetaOpers + NumArgs, dl, Ops, *this);
// Push the register mask info.
if (HasGlue)
Ops.push_back(*(Call->op_end()-2));
else
Ops.push_back(*(Call->op_end()-1));
// Push the chain (this is originally the first operand of the call, but
// becomes now the last or second to last operand).
Ops.push_back(*(Call->op_begin()));
// Push the glue flag (last operand).
if (HasGlue)
Ops.push_back(*(Call->op_end()-1));
SDVTList NodeTys;
if (IsAnyRegCC && HasDef) {
// Create the return types based on the intrinsic definition
@ -9521,13 +9506,12 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
// Replace the target specific call node with a PATCHPOINT node.
MachineSDNode *MN = DAG.getMachineNode(TargetOpcode::PATCHPOINT,
dl, NodeTys, Ops);
SDValue PPV = DAG.getNode(ISD::PATCHPOINT, dl, NodeTys, Ops);
// Update the NodeMap.
if (HasDef) {
if (IsAnyRegCC)
setValue(&CB, SDValue(MN, 0));
setValue(&CB, SDValue(PPV.getNode(), 0));
else
setValue(&CB, Result.first);
}
@ -9538,10 +9522,10 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
// value.
if (IsAnyRegCC && HasDef) {
SDValue From[] = {SDValue(Call, 0), SDValue(Call, 1)};
SDValue To[] = {SDValue(MN, 1), SDValue(MN, 2)};
SDValue To[] = {PPV.getValue(1), PPV.getValue(2)};
DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
} else
DAG.ReplaceAllUsesWith(Call, MN);
DAG.ReplaceAllUsesWith(Call, PPV.getNode());
DAG.DeleteNode(Call);
// Inform the Frame Information that we have a patchpoint in this function.

View File

@ -488,6 +488,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::VECREDUCE_FMIN: return "vecreduce_fmin";
case ISD::STACKMAP:
return "stackmap";
case ISD::PATCHPOINT:
return "patchpoint";
// Vector Predication
#define BEGIN_REGISTER_VP_SDNODE(SDID, LEGALARG, NAME, ...) \

View File

@ -2193,8 +2193,27 @@ void SelectionDAGISel::Select_ARITH_FENCE(SDNode *N) {
N->getOperand(0));
}
void SelectionDAGISel::pushStackMapLiveVariable(SmallVectorImpl<SDValue> &Ops,
SDValue OpVal, SDLoc DL) {
SDNode *OpNode = OpVal.getNode();
// FrameIndex nodes should have been directly emitted to TargetFrameIndex
// nodes at DAG-construction time.
assert(OpNode->getOpcode() != ISD::FrameIndex);
if (OpNode->getOpcode() == ISD::Constant) {
Ops.push_back(
CurDAG->getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
Ops.push_back(
CurDAG->getTargetConstant(cast<ConstantSDNode>(OpNode)->getZExtValue(),
DL, OpVal.getValueType()));
} else {
Ops.push_back(OpVal);
}
}
void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
std::vector<SDValue> Ops;
SmallVector<SDValue, 32> Ops;
auto *It = N->op_begin();
SDLoc DL(N);
@ -2213,24 +2232,8 @@ void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
Ops.push_back(Shad);
// Live variable operands.
for (; It != N->op_end(); It++) {
SDNode *OpNode = It->getNode();
SDValue O;
// FrameIndex nodes should have been directly emitted to TargetFrameIndex
// nodes at DAG-construction time.
assert(OpNode->getOpcode() != ISD::FrameIndex);
if (OpNode->getOpcode() == ISD::Constant) {
Ops.push_back(
CurDAG->getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
O = CurDAG->getTargetConstant(
cast<ConstantSDNode>(OpNode)->getZExtValue(), DL, It->getValueType());
} else {
O = *It;
}
Ops.push_back(O);
}
for (; It != N->op_end(); It++)
pushStackMapLiveVariable(Ops, *It, DL);
Ops.push_back(Chain);
Ops.push_back(InFlag);
@ -2239,6 +2242,57 @@ void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
CurDAG->SelectNodeTo(N, TargetOpcode::STACKMAP, NodeTys, Ops);
}
void SelectionDAGISel::Select_PATCHPOINT(SDNode *N) {
SmallVector<SDValue, 32> Ops;
auto *It = N->op_begin();
SDLoc DL(N);
// Cache arguments that will be moved to the end in the target node.
SDValue Chain = *It++;
Optional<SDValue> Glue;
if (It->getValueType() == MVT::Glue)
Glue = *It++;
SDValue RegMask = *It++;
// <id> operand.
SDValue ID = *It++;
assert(ID.getValueType() == MVT::i64);
Ops.push_back(ID);
// <numShadowBytes> operand.
SDValue Shad = *It++;
assert(Shad.getValueType() == MVT::i32);
Ops.push_back(Shad);
// Add the callee.
Ops.push_back(*It++);
// Add <numArgs>.
SDValue NumArgs = *It++;
assert(NumArgs.getValueType() == MVT::i32);
Ops.push_back(NumArgs);
// Calling convention.
Ops.push_back(*It++);
// Push the args for the call.
for (uint64_t I = cast<ConstantSDNode>(NumArgs)->getZExtValue(); I != 0; I--)
Ops.push_back(*It++);
// Now push the live variables.
for (; It != N->op_end(); It++)
pushStackMapLiveVariable(Ops, *It, DL);
// Finally, the regmask, chain and (if present) glue are moved to the end.
Ops.push_back(RegMask);
Ops.push_back(Chain);
if (Glue.hasValue())
Ops.push_back(Glue.getValue());
SDVTList NodeTys = N->getVTList();
CurDAG->SelectNodeTo(N, TargetOpcode::PATCHPOINT, NodeTys, Ops);
}
/// GetVBR - decode a vbr encoding whose top bit is set.
LLVM_ATTRIBUTE_ALWAYS_INLINE static uint64_t
GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
@ -2796,6 +2850,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
case ISD::STACKMAP:
Select_STACKMAP(NodeToMatch);
return;
case ISD::PATCHPOINT:
Select_PATCHPOINT(NodeToMatch);
return;
}
assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");

View File

@ -81,14 +81,14 @@
; CHECK-NEXT: .hword 8
; CHECK-NEXT: .hword 0
; CHECK-NEXT: .hword 0
; CHECK-NEXT: .word -1
; CHECK-NEXT: .word 65535
; SmallConstant
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .hword 8
; CHECK-NEXT: .hword 0
; CHECK-NEXT: .hword 0
; CHECK-NEXT: .word -1
; CHECK-NEXT: .word 65535
; SmallConstant
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0

View File

@ -84,14 +84,14 @@
; CHECK-NEXT: .short 8
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long -1
; CHECK-NEXT: .long 65535
; SmallConstant
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 8
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long -1
; CHECK-NEXT: .long 65535
; SmallConstant
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0

View File

@ -0,0 +1,154 @@
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -enable-patchpoint-liveness=false | FileCheck %s
; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
; CHECK-NEXT: __LLVM_StackMaps:
; Header
; CHECK-NEXT: .byte 3
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 0
; NumFunctions
; CHECK-NEXT: .long 1
; NumConstants
; CHECK-NEXT: .long 0
; NumRecords
; CHECK-NEXT: .long 1
; StackSizeRecord[NumFunctions]
; StackSizeRecord[0]
; CHECK-NEXT: .quad _main
; CHECK-NEXT: .quad 24
; CHECK-NEXT: .quad 1
; Constants[NumConstants] (empty)
; StkMapRecord[NumRecords]
; StkMapRecord[0]
; CHECK-NEXT: .quad 0
; CHECK-NEXT: .long {{.*}}
; CHECK-NEXT: .short {{.*}}
; NumLocations
; CHECK-NEXT: .short 11
; Location[NumLocations]
; Location[0]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 1
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[1]
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 8
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 22
; Location[2]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 1
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[3]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 16
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[4]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 16
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[5]
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 8
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 66
; Location[6]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 4
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[7]
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 8
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[8]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 4
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[9]
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 8
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
; Location[10]
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .short 1
; CHECK-NEXT: .short {{.*}}
; CHECK-NEXT: .short 0
; CHECK-NEXT: .long 0
@p32 = external global i8 addrspace(270)*
%struct1 = type {i32, i64}
%struct2 = type {i1, i1, i1}
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
define dso_local i32 @main(i32 %argc, i8** %argv) {
entry:
%i1reg = icmp eq i32 %argc, 5
%i7reg = zext i1 %i1reg to i7
%halfreg = sitofp i32 %argc to half
%ptr32 = load i8 addrspace(270)*, i8 addrspace(270)** @p32
%structreg1 = insertvalue %struct1 zeroinitializer, i32 %argc, 0
%structreg2 = insertvalue %struct2 zeroinitializer, i1 %i1reg, 0
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(
i64 0,
i32 0,
i8* null,
i32 0,
i1 %i1reg,
i7 22,
i7 %i7reg,
half 1.0,
half %halfreg,
i128 66,
; FIXME: fix and test vectors. At the moment even legally sized vectors
; are broken:
; https://github.com/llvm/llvm-project/issues/55613
;
; FIXME: test non-constant i128 once these are fixed:
; - https://github.com/llvm/llvm-project/issues/26431
; - https://github.com/llvm/llvm-project/issues/55957
i8 addrspace(270)* %ptr32,
; FIXME: The stackmap record generated for structs is incorrect:
; - https://github.com/llvm/llvm-project/issues/55649
; - https://github.com/llvm/llvm-project/issues/55957
%struct1 zeroinitializer,
%struct1 %structreg1,
%struct2 zeroinitializer,
%struct2 %structreg2)
ret i32 0
}