@@ -108,6 +108,44 @@ bool InstCombiner::ShouldChangeType(Type *From, Type *To) const {
108
108
return true ;
109
109
}
110
110
111
+ // Return true, if No Signed Wrap should be maintained for I.
112
+ // The No Signed Wrap flag can be kept if the operation "B (I.getOpcode) C",
113
+ // where both B and C should be ConstantInts, results in a constant that does
114
+ // not overflow. This function only handles the Add and Sub opcodes. For
115
+ // all other opcodes, the function conservatively returns false.
116
+ static bool MaintainNoSignedWrap (BinaryOperator &I, Value *B, Value *C) {
117
+ OverflowingBinaryOperator *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
118
+ if (!OBO || !OBO->hasNoSignedWrap ()) {
119
+ return false ;
120
+ }
121
+
122
+ // We reason about Add and Sub Only.
123
+ Instruction::BinaryOps Opcode = I.getOpcode ();
124
+ if (Opcode != Instruction::Add &&
125
+ Opcode != Instruction::Sub) {
126
+ return false ;
127
+ }
128
+
129
+ ConstantInt *CB = dyn_cast<ConstantInt>(B);
130
+ ConstantInt *CC = dyn_cast<ConstantInt>(C);
131
+
132
+ if (!CB || !CC) {
133
+ return false ;
134
+ }
135
+
136
+ const APInt &BVal = CB->getValue ();
137
+ const APInt &CVal = CC->getValue ();
138
+ bool Overflow = false ;
139
+
140
+ if (Opcode == Instruction::Add) {
141
+ BVal.sadd_ov (CVal, Overflow);
142
+ } else {
143
+ BVal.ssub_ov (CVal, Overflow);
144
+ }
145
+
146
+ return !Overflow;
147
+ }
148
+
111
149
112
150
// / SimplifyAssociativeOrCommutative - This performs a few simplifications for
113
151
// / operators which are associative or commutative:
@@ -159,7 +197,13 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
159
197
I.setOperand (1 , V);
160
198
// Conservatively clear the optional flags, since they may not be
161
199
// preserved by the reassociation.
162
- I.clearSubclassOptionalData ();
200
+ if (MaintainNoSignedWrap (I, B, C)) {
201
+ I.clearSubclassOptionalData ();
202
+ I.setHasNoSignedWrap (true );
203
+ } else {
204
+ I.clearSubclassOptionalData ();
205
+ }
206
+
163
207
Changed = true ;
164
208
++NumReassoc;
165
209
continue ;
@@ -241,14 +285,21 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
241
285
Constant *C2 = cast<Constant>(Op1->getOperand (1 ));
242
286
243
287
Constant *Folded = ConstantExpr::get (Opcode, C1, C2);
244
- Instruction *New = BinaryOperator::Create (Opcode, A, B);
288
+ BinaryOperator *New = BinaryOperator::Create (Opcode, A, B);
245
289
InsertNewInstWith (New, I);
246
290
New->takeName (Op1);
247
291
I.setOperand (0 , New);
248
292
I.setOperand (1 , Folded);
249
293
// Conservatively clear the optional flags, since they may not be
250
294
// preserved by the reassociation.
251
- I.clearSubclassOptionalData ();
295
+ if (MaintainNoSignedWrap (I, C1, C2)) {
296
+ I.clearSubclassOptionalData ();
297
+ I.setHasNoSignedWrap (true );
298
+ New->setHasNoSignedWrap (true );
299
+ } else {
300
+ I.clearSubclassOptionalData ();
301
+ }
302
+
252
303
Changed = true ;
253
304
continue ;
254
305
}
0 commit comments