@@ -71,89 +71,78 @@ static bool isExtractExtractCheap(Instruction *Ext0, Instruction *Ext1,
71
71
72
72
// Extra uses of the extracts mean that we include those costs in the
73
73
// vector total because those instructions will not be eliminated.
74
- int ScalarCost, VectorCost ;
74
+ int OldCost, NewCost ;
75
75
if (Ext0->getOperand (0 ) == Ext1->getOperand (0 )) {
76
76
// Handle a special case. If the 2 operands are identical, adjust the
77
77
// formulas to account for that. The extra use charge allows for either the
78
78
// CSE'd pattern or an unoptimized form with identical values:
79
79
// opcode (extelt V, C), (extelt V, C) --> extelt (opcode V, V), C
80
80
bool HasUseTax = Ext0 == Ext1 ? !Ext0->hasNUses (2 )
81
81
: !Ext0->hasOneUse () || !Ext1->hasOneUse ();
82
- ScalarCost = ExtractCost + ScalarOpCost;
83
- VectorCost = VectorOpCost + ExtractCost + HasUseTax * ExtractCost;
82
+ OldCost = ExtractCost + ScalarOpCost;
83
+ NewCost = VectorOpCost + ExtractCost + HasUseTax * ExtractCost;
84
84
} else {
85
85
// Handle the general case. Each extract is actually a different value:
86
86
// opcode (extelt V0, C), (extelt V1, C) --> extelt (opcode V0, V1), C
87
- ScalarCost = 2 * ExtractCost + ScalarOpCost;
88
- VectorCost = VectorOpCost + ExtractCost +
89
- !Ext0->hasOneUse () * ExtractCost +
90
- !Ext1->hasOneUse () * ExtractCost;
87
+ OldCost = 2 * ExtractCost + ScalarOpCost;
88
+ NewCost = VectorOpCost + ExtractCost + !Ext0->hasOneUse () * ExtractCost +
89
+ !Ext1->hasOneUse () * ExtractCost;
91
90
}
92
91
// TODO: The cost comparison should not differ based on opcode. Either we
93
92
// want to be uniformly more or less aggressive in deciding if a vector
94
93
// operation should replace the scalar operation.
95
- return IsBinOp ? ScalarCost <= VectorCost : ScalarCost < VectorCost ;
94
+ return IsBinOp ? OldCost <= NewCost : OldCost < NewCost ;
96
95
}
97
96
98
97
// / Try to reduce extract element costs by converting scalar compares to vector
99
98
// / compares followed by extract.
100
- // / cmp (ext0 V0, C0), (ext1 V1, C1)
101
- static bool foldExtExtCmp (Instruction *Ext0, Value *V0, uint64_t C0,
102
- Instruction *Ext1, Value *V1, uint64_t C1,
99
+ // / cmp (ext0 V0, C), (ext1 V1, C)
100
+ static void foldExtExtCmp (Instruction *Ext0, Instruction *Ext1,
103
101
Instruction &I, const TargetTransformInfo &TTI) {
104
102
assert (isa<CmpInst>(&I) && " Expected a compare" );
105
103
106
- // TODO: Handle C0 != C1 by shuffling 1 of the operands.
107
- if (C0 != C1)
108
- return false ;
109
-
110
- if (isExtractExtractCheap (Ext0, Ext1, I.getOpcode (), TTI))
111
- return false ;
112
-
113
104
// cmp Pred (extelt V0, C), (extelt V1, C) --> extelt (cmp Pred V0, V1), C
114
105
++NumVecCmp;
115
106
IRBuilder<> Builder (&I);
116
107
CmpInst::Predicate Pred = cast<CmpInst>(&I)->getPredicate ();
108
+ Value *V0 = Ext0->getOperand (0 ), *V1 = Ext1->getOperand (0 );
117
109
Value *VecCmp =
118
110
Ext0->getType ()->isFloatingPointTy () ? Builder.CreateFCmp (Pred, V0, V1)
119
111
: Builder.CreateICmp (Pred, V0, V1);
120
112
Value *Extract = Builder.CreateExtractElement (VecCmp, Ext0->getOperand (1 ));
121
113
I.replaceAllUsesWith (Extract);
122
- return true ;
123
114
}
124
115
125
116
// / Try to reduce extract element costs by converting scalar binops to vector
126
117
// / binops followed by extract.
127
- // / bo (ext0 V0, C0), (ext1 V1, C1)
128
- static bool foldExtExtBinop (Instruction *Ext0, Value *V0, uint64_t C0,
129
- Instruction *Ext1, Value *V1, uint64_t C1,
118
+ // / bo (ext0 V0, C), (ext1 V1, C)
119
+ static void foldExtExtBinop (Instruction *Ext0, Instruction *Ext1,
130
120
Instruction &I, const TargetTransformInfo &TTI) {
131
121
assert (isa<BinaryOperator>(&I) && " Expected a binary operator" );
132
122
133
- // TODO: Handle C0 != C1 by shuffling 1 of the operands.
134
- if (C0 != C1)
135
- return false ;
136
-
137
- if (isExtractExtractCheap (Ext0, Ext1, I.getOpcode (), TTI))
138
- return false ;
139
-
140
123
// bo (extelt V0, C), (extelt V1, C) --> extelt (bo V0, V1), C
141
124
++NumVecBO;
142
125
IRBuilder<> Builder (&I);
143
- Value *NewBO =
126
+ Value *V0 = Ext0->getOperand (0 ), *V1 = Ext1->getOperand (0 );
127
+ Value *VecBO =
144
128
Builder.CreateBinOp (cast<BinaryOperator>(&I)->getOpcode (), V0, V1);
145
- if (auto *VecBOInst = dyn_cast<Instruction>(NewBO)) {
146
- // All IR flags are safe to back-propagate because any potential poison
147
- // created in unused vector elements is discarded by the extract.
129
+
130
+ // All IR flags are safe to back-propagate because any potential poison
131
+ // created in unused vector elements is discarded by the extract.
132
+ if (auto *VecBOInst = dyn_cast<Instruction>(VecBO))
148
133
VecBOInst->copyIRFlags (&I);
149
- }
150
- Value *Extract = Builder.CreateExtractElement (NewBO , Ext0->getOperand (1 ));
134
+
135
+ Value *Extract = Builder.CreateExtractElement (VecBO , Ext0->getOperand (1 ));
151
136
I.replaceAllUsesWith (Extract);
152
- return true ;
153
137
}
154
138
155
139
// / Match an instruction with extracted vector operands.
156
140
static bool foldExtractExtract (Instruction &I, const TargetTransformInfo &TTI) {
141
+ // It is not safe to transform things like div, urem, etc. because we may
142
+ // create undefined behavior when executing those on unknown vector elements.
143
+ if (!isSafeToSpeculativelyExecute (&I))
144
+ return false ;
145
+
157
146
Instruction *Ext0, *Ext1;
158
147
CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE;
159
148
if (!match (&I, m_Cmp (Pred, m_Instruction (Ext0), m_Instruction (Ext1))) &&
@@ -167,15 +156,19 @@ static bool foldExtractExtract(Instruction &I, const TargetTransformInfo &TTI) {
167
156
V0->getType () != V1->getType ())
168
157
return false ;
169
158
170
- if (Pred != CmpInst::BAD_ICMP_PREDICATE)
171
- return foldExtExtCmp (Ext0, V0, C0, Ext1, V1, C1, I, TTI);
159
+ // TODO: Handle C0 != C1 by shuffling 1 of the operands.
160
+ if (C0 != C1)
161
+ return false ;
172
162
173
- // It is not safe to transform things like div, urem, etc. because we may
174
- // create undefined behavior when executing those on unknown vector elements.
175
- if (isSafeToSpeculativelyExecute (&I))
176
- return foldExtExtBinop (Ext0, V0, C0, Ext1, V1, C1, I, TTI);
163
+ if (isExtractExtractCheap (Ext0, Ext1, I.getOpcode (), TTI))
164
+ return false ;
165
+
166
+ if (Pred != CmpInst::BAD_ICMP_PREDICATE)
167
+ foldExtExtCmp (Ext0, Ext1, I, TTI);
168
+ else
169
+ foldExtExtBinop (Ext0, Ext1, I, TTI);
177
170
178
- return false ;
171
+ return true ;
179
172
}
180
173
181
174
// / This is the entry point for all transforms. Pass manager differences are
0 commit comments