1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "ReduceOperands.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/InstIterator.h"
12 #include "llvm/IR/InstrTypes.h"
13 #include "llvm/IR/Operator.h"
14 #include "llvm/IR/PatternMatch.h"
15 #include "llvm/IR/Type.h"
18 using namespace PatternMatch
;
21 extractOperandsFromModule(Oracle
&O
, ReducerWorkItem
&WorkItem
,
22 function_ref
<Value
*(Use
&)> ReduceValue
) {
23 Module
&Program
= WorkItem
.getModule();
25 for (auto &F
: Program
.functions()) {
26 for (auto &I
: instructions(&F
)) {
27 if (PHINode
*Phi
= dyn_cast
<PHINode
>(&I
)) {
28 for (auto &Op
: Phi
->incoming_values()) {
29 if (!O
.shouldKeep()) {
30 if (Value
*Reduced
= ReduceValue(Op
))
31 Phi
->setIncomingValueForBlock(Phi
->getIncomingBlock(Op
), Reduced
);
38 for (auto &Op
: I
.operands()) {
39 if (Value
*Reduced
= ReduceValue(Op
)) {
48 static bool isOne(Use
&Op
) {
49 auto *C
= dyn_cast
<Constant
>(Op
);
50 return C
&& C
->isOneValue();
53 static bool isZero(Use
&Op
) {
54 auto *C
= dyn_cast
<Constant
>(Op
);
55 return C
&& C
->isNullValue();
58 static bool isZeroOrOneFP(Value
*Op
) {
60 return match(Op
, m_APFloat(C
)) &&
61 ((C
->isZero() && !C
->isNegative()) || C
->isExactlyValue(1.0));
64 static bool shouldReduceOperand(Use
&Op
) {
65 Type
*Ty
= Op
->getType();
66 if (Ty
->isLabelTy() || Ty
->isMetadataTy())
68 // TODO: be more precise about which GEP operands we can reduce (e.g. array
70 if (isa
<GEPOperator
>(Op
.getUser()))
72 if (auto *CB
= dyn_cast
<CallBase
>(Op
.getUser())) {
73 if (&CB
->getCalledOperandUse() == &Op
)
79 static bool switchCaseExists(Use
&Op
, ConstantInt
*CI
) {
80 SwitchInst
*SI
= dyn_cast
<SwitchInst
>(Op
.getUser());
83 return SI
->findCaseValue(CI
) != SI
->case_default();
86 void llvm::reduceOperandsOneDeltaPass(TestRunner
&Test
) {
87 auto ReduceValue
= [](Use
&Op
) -> Value
* {
88 if (!shouldReduceOperand(Op
))
91 Type
*Ty
= Op
->getType();
92 if (auto *IntTy
= dyn_cast
<IntegerType
>(Ty
)) {
93 // Don't duplicate an existing switch case.
94 if (switchCaseExists(Op
, ConstantInt::get(IntTy
, 1)))
96 // Don't replace existing ones and zeroes.
97 return (isOne(Op
) || isZero(Op
)) ? nullptr : ConstantInt::get(IntTy
, 1);
100 if (Ty
->isFloatingPointTy())
101 return isZeroOrOneFP(Op
) ? nullptr : ConstantFP::get(Ty
, 1.0);
103 if (VectorType
*VT
= dyn_cast
<VectorType
>(Ty
)) {
104 if (isOne(Op
) || isZero(Op
) || isZeroOrOneFP(Op
))
107 Type
*ElementType
= VT
->getElementType();
109 if (ElementType
->isFloatingPointTy()) {
110 C
= ConstantFP::get(ElementType
, 1.0);
111 } else if (IntegerType
*IntTy
= dyn_cast
<IntegerType
>(ElementType
)) {
112 C
= ConstantInt::get(IntTy
, 1);
116 return ConstantVector::getSplat(VT
->getElementCount(), C
);
123 [ReduceValue
](Oracle
&O
, ReducerWorkItem
&WorkItem
) {
124 extractOperandsFromModule(O
, WorkItem
, ReduceValue
);
126 "Reducing Operands to one");
129 void llvm::reduceOperandsZeroDeltaPass(TestRunner
&Test
) {
130 auto ReduceValue
= [](Use
&Op
) -> Value
* {
131 if (!shouldReduceOperand(Op
))
133 // Don't duplicate an existing switch case.
134 if (auto *IntTy
= dyn_cast
<IntegerType
>(Op
->getType()))
135 if (switchCaseExists(Op
, ConstantInt::get(IntTy
, 0)))
137 // Don't replace existing zeroes.
138 return isZero(Op
) ? nullptr : Constant::getNullValue(Op
->getType());
142 [ReduceValue
](Oracle
&O
, ReducerWorkItem
&Program
) {
143 extractOperandsFromModule(O
, Program
, ReduceValue
);
145 "Reducing Operands to zero");
148 void llvm::reduceOperandsNaNDeltaPass(TestRunner
&Test
) {
149 auto ReduceValue
= [](Use
&Op
) -> Value
* {
150 Type
*Ty
= Op
->getType();
151 if (!Ty
->isFPOrFPVectorTy())
154 // Prefer 0.0 or 1.0 over NaN.
156 // TODO: Preferring NaN may make more sense because FP operations are more
157 // universally foldable.
158 if (match(Op
.get(), m_NaN()) || isZeroOrOneFP(Op
.get()))
161 if (VectorType
*VT
= dyn_cast
<VectorType
>(Ty
)) {
162 return ConstantVector::getSplat(VT
->getElementCount(),
163 ConstantFP::getQNaN(VT
->getElementType()));
166 return ConstantFP::getQNaN(Ty
);
170 [ReduceValue
](Oracle
&O
, ReducerWorkItem
&Program
) {
171 extractOperandsFromModule(O
, Program
, ReduceValue
);
173 "Reducing Operands to NaN");