Skip to content

Commit 70f4b59

Browse files
authored
Add llvm.vector.partial.reduce.fadd intrinsic (#159776)
With this intrinsic, and supporting SelectionDAG nodes, we can better make use of instructions such as AArch64's `FDOT`.
1 parent 411ea8e commit 70f4b59

18 files changed

+501
-72
lines changed

llvm/docs/LangRef.rst

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -20368,6 +20368,77 @@ Arguments:
2036820368
""""""""""
2036920369
The argument to this intrinsic must be a vector of floating-point values.
2037020370

20371+
Vector Partial Reduction Intrinsics
20372+
-----------------------------------
20373+
20374+
Partial reductions of vectors can be expressed using the intrinsics described in
20375+
this section. Each one reduces the concatenation of the two vector arguments
20376+
down to the number of elements of the result vector type.
20377+
20378+
Other than the reduction operator (e.g. add, fadd), the way in which the
20379+
concatenated arguments is reduced is entirely unspecified. By their nature these
20380+
intrinsics are not expected to be useful in isolation but can instead be used to
20381+
implement the first phase of an overall reduction operation.
20382+
20383+
The typical use case is loop vectorization where reductions are split into an
20384+
in-loop phase, where maintaining an unordered vector result is important for
20385+
performance, and an out-of-loop phase is required to calculate the final scalar
20386+
result.
20387+
20388+
By avoiding the introduction of new ordering constraints, these intrinsics
20389+
enhance the ability to leverage a target's accumulation instructions.
20390+
20391+
'``llvm.vector.partial.reduce.add.*``' Intrinsic
20392+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20393+
20394+
Syntax:
20395+
"""""""
20396+
This is an overloaded intrinsic.
20397+
20398+
::
20399+
20400+
declare <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v4i32.v8i32(<4 x i32> %a, <8 x i32> %b)
20401+
declare <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v4i32.v16i32(<4 x i32> %a, <16 x i32> %b)
20402+
declare <vscale x 4 x i32> @llvm.vector.partial.reduce.add.nxv4i32.nxv4i32.nxv8i32(<vscale x 4 x i32> %a, <vscale x 8 x i32> %b)
20403+
declare <vscale x 4 x i32> @llvm.vector.partial.reduce.add.nxv4i32.nxv4i32.nxv16i32(<vscale x 4 x i32> %a, <vscale x 16 x i32> %b)
20404+
20405+
Arguments:
20406+
""""""""""
20407+
20408+
The first argument is an integer vector with the same type as the result.
20409+
20410+
The second argument is a vector with a length that is a known integer multiple
20411+
of the result's type, while maintaining the same element type.
20412+
20413+
'``llvm.vector.partial.reduce.fadd.*``' Intrinsic
20414+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20415+
20416+
Syntax:
20417+
"""""""
20418+
This is an overloaded intrinsic.
20419+
20420+
::
20421+
20422+
declare <4 x f32> @llvm.vector.partial.reduce.fadd.v4f32.v8f32(<4 x f32> %a, <8 x f32> %b)
20423+
declare <vscale x 4 x f32> @llvm.vector.partial.reduce.fadd.nxv4f32.nxv8f32(<vscale x 4 x f32> %a, <vscale x 8 x f32> %b)
20424+
20425+
Arguments:
20426+
""""""""""
20427+
20428+
The first argument is a floating-point vector with the same type as the result.
20429+
20430+
The second argument is a vector with a length that is a known integer multiple
20431+
of the result's type, while maintaining the same element type.
20432+
20433+
Semantics:
20434+
""""""""""
20435+
20436+
As the way in which the arguments to this floating-point intrinsic are reduced
20437+
is unspecified, this intrinsic will assume floating-point reassociation and
20438+
contraction can be leveraged to implement the reduction, which may result in
20439+
variations to the results due to reordering or by lowering to different
20440+
instructions (including combining multiple instructions into a single one).
20441+
2037120442
'``llvm.vector.insert``' Intrinsic
2037220443
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2037320444

@@ -20741,50 +20812,6 @@ Note that it has the following implications:
2074120812
- If ``%cnt`` is non-zero, the return value is non-zero as well.
2074220813
- If ``%cnt`` is less than or equal to ``%max_lanes``, the return value is equal to ``%cnt``.
2074320814

20744-
'``llvm.vector.partial.reduce.add.*``' Intrinsic
20745-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20746-
20747-
Syntax:
20748-
"""""""
20749-
This is an overloaded intrinsic.
20750-
20751-
::
20752-
20753-
declare <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v4i32.v8i32(<4 x i32> %a, <8 x i32> %b)
20754-
declare <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v4i32.v16i32(<4 x i32> %a, <16 x i32> %b)
20755-
declare <vscale x 4 x i32> @llvm.vector.partial.reduce.add.nxv4i32.nxv4i32.nxv8i32(<vscale x 4 x i32> %a, <vscale x 8 x i32> %b)
20756-
declare <vscale x 4 x i32> @llvm.vector.partial.reduce.add.nxv4i32.nxv4i32.nxv16i32(<vscale x 4 x i32> %a, <vscale x 16 x i32> %b)
20757-
20758-
Overview:
20759-
"""""""""
20760-
20761-
The '``llvm.vector.partial.reduce.add.*``' intrinsics reduce the
20762-
concatenation of the two vector arguments down to the number of elements of the
20763-
result vector type.
20764-
20765-
Arguments:
20766-
""""""""""
20767-
20768-
The first argument is an integer vector with the same type as the result.
20769-
20770-
The second argument is a vector with a length that is a known integer multiple
20771-
of the result's type, while maintaining the same element type.
20772-
20773-
Semantics:
20774-
""""""""""
20775-
20776-
Other than the reduction operator (e.g., add) the way in which the concatenated
20777-
arguments is reduced is entirely unspecified. By their nature these intrinsics
20778-
are not expected to be useful in isolation but instead implement the first phase
20779-
of an overall reduction operation.
20780-
20781-
The typical use case is loop vectorization where reductions are split into an
20782-
in-loop phase, where maintaining an unordered vector result is important for
20783-
performance, and an out-of-loop phase to calculate the final scalar result.
20784-
20785-
By avoiding the introduction of new ordering constraints, these intrinsics
20786-
enhance the ability to leverage a target's accumulation instructions.
20787-
2078820815
'``llvm.experimental.vector.histogram.*``' Intrinsic
2078920816
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2079020817

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,7 @@ enum NodeType {
15161516
PARTIAL_REDUCE_SMLA, // sext, sext
15171517
PARTIAL_REDUCE_UMLA, // zext, zext
15181518
PARTIAL_REDUCE_SUMLA, // sext, zext
1519+
PARTIAL_REDUCE_FMLA, // fpext, fpext
15191520

15201521
// The `llvm.experimental.stackmap` intrinsic.
15211522
// Operands: input chain, glue, <id>, <numShadowBytes>, [live0[, live1...]]

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,10 @@ LLVM_ABI bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
19491949
/// be zero.
19501950
LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false);
19511951

1952+
/// Return true if the value is a constant floating-point value, or a splatted
1953+
/// vector of a constant floating-point value, of 1.0 (with no undefs).
1954+
LLVM_ABI bool isOneOrOneSplatFP(SDValue V, bool AllowUndefs = false);
1955+
19521956
/// Return true if the value is a constant -1 integer or a splatted vector of a
19531957
/// constant -1 integer (with no undefs).
19541958
/// Does not permit build vector implicit truncation.

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,7 @@ class LLVM_ABI TargetLoweringBase {
16791679
LegalizeAction getPartialReduceMLAAction(unsigned Opc, EVT AccVT,
16801680
EVT InputVT) const {
16811681
assert(Opc == ISD::PARTIAL_REDUCE_SMLA || Opc == ISD::PARTIAL_REDUCE_UMLA ||
1682-
Opc == ISD::PARTIAL_REDUCE_SUMLA);
1682+
Opc == ISD::PARTIAL_REDUCE_SUMLA || Opc == ISD::PARTIAL_REDUCE_FMLA);
16831683
PartialReduceActionTypes Key = {Opc, AccVT.getSimpleVT().SimpleTy,
16841684
InputVT.getSimpleVT().SimpleTy};
16851685
auto It = PartialReduceMLAActions.find(Key);
@@ -2793,7 +2793,7 @@ class LLVM_ABI TargetLoweringBase {
27932793
void setPartialReduceMLAAction(unsigned Opc, MVT AccVT, MVT InputVT,
27942794
LegalizeAction Action) {
27952795
assert(Opc == ISD::PARTIAL_REDUCE_SMLA || Opc == ISD::PARTIAL_REDUCE_UMLA ||
2796-
Opc == ISD::PARTIAL_REDUCE_SUMLA);
2796+
Opc == ISD::PARTIAL_REDUCE_SUMLA || Opc == ISD::PARTIAL_REDUCE_FMLA);
27972797
assert(AccVT.isValid() && InputVT.isValid() &&
27982798
"setPartialReduceMLAAction types aren't valid");
27992799
PartialReduceActionTypes Key = {Opc, AccVT.SimpleTy, InputVT.SimpleTy};

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,6 +2813,10 @@ def int_vector_partial_reduce_add : DefaultAttrsIntrinsic<[LLVMMatchType<0>],
28132813
[IntrNoMem,
28142814
IntrSpeculatable]>;
28152815

2816+
def int_vector_partial_reduce_fadd : DefaultAttrsIntrinsic<[LLVMMatchType<0>],
2817+
[llvm_anyfloat_ty, llvm_anyfloat_ty],
2818+
[IntrNoMem]>;
2819+
28162820
//===----------------- Pointer Authentication Intrinsics ------------------===//
28172821
//
28182822

llvm/include/llvm/Target/TargetSelectionDAG.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,8 @@ def partial_reduce_smla : SDNode<"ISD::PARTIAL_REDUCE_SMLA",
527527
SDTPartialReduceMLA>;
528528
def partial_reduce_sumla : SDNode<"ISD::PARTIAL_REDUCE_SUMLA",
529529
SDTPartialReduceMLA>;
530+
def partial_reduce_fmla : SDNode<"ISD::PARTIAL_REDUCE_FMLA",
531+
SDTPartialReduceMLA>;
530532

531533
def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>;
532534
def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>;

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
20422042
case ISD::PARTIAL_REDUCE_SMLA:
20432043
case ISD::PARTIAL_REDUCE_UMLA:
20442044
case ISD::PARTIAL_REDUCE_SUMLA:
2045+
case ISD::PARTIAL_REDUCE_FMLA:
20452046
return visitPARTIAL_REDUCE_MLA(N);
20462047
case ISD::VECTOR_COMPRESS: return visitVECTOR_COMPRESS(N);
20472048
case ISD::LIFETIME_END: return visitLIFETIME_END(N);
@@ -13006,6 +13007,9 @@ SDValue DAGCombiner::visitPARTIAL_REDUCE_MLA(SDNode *N) {
1300613007
//
1300713008
// partial_reduce_*mla(acc, mul(ext(x), splat(C)), splat(1))
1300813009
// -> partial_reduce_*mla(acc, x, C)
13010+
//
13011+
// partial_reduce_fmla(acc, fmul(fpext(a), fpext(b)), splat(1.0))
13012+
// -> partial_reduce_fmla(acc, a, b)
1300913013
SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *N) {
1301013014
SDLoc DL(N);
1301113015
auto *Context = DAG.getContext();
@@ -13014,7 +13018,7 @@ SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *N) {
1301413018
SDValue Op2 = N->getOperand(2);
1301513019

1301613020
unsigned Opc = Op1->getOpcode();
13017-
if (Opc != ISD::MUL && Opc != ISD::SHL)
13021+
if (Opc != ISD::MUL && Opc != ISD::FMUL && Opc != ISD::SHL)
1301813022
return SDValue();
1301913023

1302013024
SDValue LHS = Op1->getOperand(0);
@@ -13033,20 +13037,24 @@ SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *N) {
1303313037
Opc = ISD::MUL;
1303413038
}
1303513039

13036-
APInt C;
13037-
if (Opc != ISD::MUL || !ISD::isConstantSplatVector(Op2.getNode(), C) ||
13038-
!C.isOne())
13040+
if (!(Opc == ISD::MUL && llvm::isOneOrOneSplat(Op2)) &&
13041+
!(Opc == ISD::FMUL && llvm::isOneOrOneSplatFP(Op2)))
1303913042
return SDValue();
1304013043

13044+
auto IsIntOrFPExtOpcode = [](unsigned int Opcode) {
13045+
return (ISD::isExtOpcode(Opcode) || Opcode == ISD::FP_EXTEND);
13046+
};
13047+
1304113048
unsigned LHSOpcode = LHS->getOpcode();
13042-
if (!ISD::isExtOpcode(LHSOpcode))
13049+
if (!IsIntOrFPExtOpcode(LHSOpcode))
1304313050
return SDValue();
1304413051

1304513052
SDValue LHSExtOp = LHS->getOperand(0);
1304613053
EVT LHSExtOpVT = LHSExtOp.getValueType();
1304713054

1304813055
// partial_reduce_*mla(acc, mul(ext(x), splat(C)), splat(1))
1304913056
// -> partial_reduce_*mla(acc, x, C)
13057+
APInt C;
1305013058
if (ISD::isConstantSplatVector(RHS.getNode(), C)) {
1305113059
// TODO: Make use of partial_reduce_sumla here
1305213060
APInt CTrunc = C.trunc(LHSExtOpVT.getScalarSizeInBits());
@@ -13071,7 +13079,7 @@ SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *N) {
1307113079
}
1307213080

1307313081
unsigned RHSOpcode = RHS->getOpcode();
13074-
if (!ISD::isExtOpcode(RHSOpcode))
13082+
if (!IsIntOrFPExtOpcode(RHSOpcode))
1307513083
return SDValue();
1307613084

1307713085
SDValue RHSExtOp = RHS->getOperand(0);
@@ -13088,6 +13096,8 @@ SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *N) {
1308813096
else if (LHSOpcode == ISD::ZERO_EXTEND && RHSOpcode == ISD::SIGN_EXTEND) {
1308913097
NewOpc = ISD::PARTIAL_REDUCE_SUMLA;
1309013098
std::swap(LHSExtOp, RHSExtOp);
13099+
} else if (LHSOpcode == ISD::FP_EXTEND && RHSOpcode == ISD::FP_EXTEND) {
13100+
NewOpc = ISD::PARTIAL_REDUCE_FMLA;
1309113101
} else
1309213102
return SDValue();
1309313103
// For a 2-stage extend the signedness of both of the extends must match
@@ -13115,30 +13125,33 @@ SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *N) {
1311513125
// -> partial.reduce.smla(acc, op, splat(trunc(1)))
1311613126
// partial.reduce.sumla(acc, sext(op), splat(1))
1311713127
// -> partial.reduce.smla(acc, op, splat(trunc(1)))
13128+
// partial.reduce.fmla(acc, fpext(op), splat(1.0))
13129+
// -> partial.reduce.fmla(acc, op, splat(1.0))
1311813130
SDValue DAGCombiner::foldPartialReduceAdd(SDNode *N) {
1311913131
SDLoc DL(N);
1312013132
SDValue Acc = N->getOperand(0);
1312113133
SDValue Op1 = N->getOperand(1);
1312213134
SDValue Op2 = N->getOperand(2);
1312313135

13124-
APInt ConstantOne;
13125-
if (!ISD::isConstantSplatVector(Op2.getNode(), ConstantOne) ||
13126-
!ConstantOne.isOne())
13136+
if (!llvm::isOneOrOneSplat(Op2) && !llvm::isOneOrOneSplatFP(Op2))
1312713137
return SDValue();
1312813138

1312913139
unsigned Op1Opcode = Op1.getOpcode();
13130-
if (!ISD::isExtOpcode(Op1Opcode))
13140+
if (!ISD::isExtOpcode(Op1Opcode) && Op1Opcode != ISD::FP_EXTEND)
1313113141
return SDValue();
1313213142

13133-
bool Op1IsSigned = Op1Opcode == ISD::SIGN_EXTEND;
13143+
bool Op1IsSigned =
13144+
Op1Opcode == ISD::SIGN_EXTEND || Op1Opcode == ISD::FP_EXTEND;
1313413145
bool NodeIsSigned = N->getOpcode() != ISD::PARTIAL_REDUCE_UMLA;
1313513146
EVT AccElemVT = Acc.getValueType().getVectorElementType();
1313613147
if (Op1IsSigned != NodeIsSigned &&
1313713148
Op1.getValueType().getVectorElementType() != AccElemVT)
1313813149
return SDValue();
1313913150

13140-
unsigned NewOpcode =
13141-
Op1IsSigned ? ISD::PARTIAL_REDUCE_SMLA : ISD::PARTIAL_REDUCE_UMLA;
13151+
unsigned NewOpcode = N->getOpcode() == ISD::PARTIAL_REDUCE_FMLA
13152+
? ISD::PARTIAL_REDUCE_FMLA
13153+
: Op1IsSigned ? ISD::PARTIAL_REDUCE_SMLA
13154+
: ISD::PARTIAL_REDUCE_UMLA;
1314213155

1314313156
SDValue UnextOp1 = Op1.getOperand(0);
1314413157
EVT UnextOp1VT = UnextOp1.getValueType();
@@ -13148,8 +13161,12 @@ SDValue DAGCombiner::foldPartialReduceAdd(SDNode *N) {
1314813161
TLI.getTypeToTransformTo(*Context, UnextOp1VT)))
1314913162
return SDValue();
1315013163

13164+
SDValue Constant = N->getOpcode() == ISD::PARTIAL_REDUCE_FMLA
13165+
? DAG.getConstantFP(1, DL, UnextOp1VT)
13166+
: DAG.getConstant(1, DL, UnextOp1VT);
13167+
1315113168
return DAG.getNode(NewOpcode, DL, N->getValueType(0), Acc, UnextOp1,
13152-
DAG.getConstant(1, DL, UnextOp1VT));
13169+
Constant);
1315313170
}
1315413171

1315513172
SDValue DAGCombiner::visitVP_STRIDED_LOAD(SDNode *N) {

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
534534
case ISD::PARTIAL_REDUCE_UMLA:
535535
case ISD::PARTIAL_REDUCE_SMLA:
536536
case ISD::PARTIAL_REDUCE_SUMLA:
537+
case ISD::PARTIAL_REDUCE_FMLA:
537538
Action =
538539
TLI.getPartialReduceMLAAction(Op.getOpcode(), Node->getValueType(0),
539540
Node->getOperand(1).getValueType());
@@ -1243,6 +1244,7 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
12431244
case ISD::PARTIAL_REDUCE_UMLA:
12441245
case ISD::PARTIAL_REDUCE_SMLA:
12451246
case ISD::PARTIAL_REDUCE_SUMLA:
1247+
case ISD::PARTIAL_REDUCE_FMLA:
12461248
Results.push_back(TLI.expandPartialReduceMLA(Node, DAG));
12471249
return;
12481250
case ISD::VECREDUCE_SEQ_FADD:

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
14741474
case ISD::PARTIAL_REDUCE_UMLA:
14751475
case ISD::PARTIAL_REDUCE_SMLA:
14761476
case ISD::PARTIAL_REDUCE_SUMLA:
1477+
case ISD::PARTIAL_REDUCE_FMLA:
14771478
SplitVecRes_PARTIAL_REDUCE_MLA(N, Lo, Hi);
14781479
break;
14791480
case ISD::GET_ACTIVE_LANE_MASK:
@@ -3689,6 +3690,7 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
36893690
case ISD::PARTIAL_REDUCE_UMLA:
36903691
case ISD::PARTIAL_REDUCE_SMLA:
36913692
case ISD::PARTIAL_REDUCE_SUMLA:
3693+
case ISD::PARTIAL_REDUCE_FMLA:
36923694
Res = SplitVecOp_PARTIAL_REDUCE_MLA(N);
36933695
break;
36943696
}

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8404,7 +8404,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
84048404
}
84058405
case ISD::PARTIAL_REDUCE_UMLA:
84068406
case ISD::PARTIAL_REDUCE_SMLA:
8407-
case ISD::PARTIAL_REDUCE_SUMLA: {
8407+
case ISD::PARTIAL_REDUCE_SUMLA:
8408+
case ISD::PARTIAL_REDUCE_FMLA: {
84088409
[[maybe_unused]] EVT AccVT = N1.getValueType();
84098410
[[maybe_unused]] EVT Input1VT = N2.getValueType();
84108411
[[maybe_unused]] EVT Input2VT = N3.getValueType();
@@ -13064,6 +13065,11 @@ bool llvm::isOneOrOneSplat(SDValue N, bool AllowUndefs) {
1306413065
return C && C->isOne();
1306513066
}
1306613067

13068+
bool llvm::isOneOrOneSplatFP(SDValue N, bool AllowUndefs) {
13069+
ConstantFPSDNode *C = isConstOrConstSplatFP(N, AllowUndefs);
13070+
return C && C->isExactlyValue(1.0);
13071+
}
13072+
1306713073
bool llvm::isAllOnesOrAllOnesSplat(SDValue N, bool AllowUndefs) {
1306813074
N = peekThroughBitcasts(N);
1306913075
unsigned BitWidth = N.getScalarValueSizeInBits();

0 commit comments

Comments
 (0)