@@ -115,6 +115,19 @@ Negator::~Negator() {
115
115
}
116
116
#endif
117
117
118
+ // Due to the InstCombine's worklist management, there are no guarantees that
119
+ // each instruction we'll encounter has been visited by InstCombine already.
120
+ // In particular, most importantly for us, that means we have to canonicalize
121
+ // constants to RHS ourselves, since that is helpful sometimes.
122
+ std::array<Value *, 2 > Negator::getSortedOperandsOfBinOp (Instruction *I) {
123
+ assert (I->getNumOperands () == 2 && " Only for binops!" );
124
+ std::array<Value *, 2 > Ops{I->getOperand (0 ), I->getOperand (1 )};
125
+ if (I->isCommutative () && InstCombiner::getComplexity (I->getOperand (0 )) <
126
+ InstCombiner::getComplexity (I->getOperand (1 )))
127
+ std::swap (Ops[0 ], Ops[1 ]);
128
+ return Ops;
129
+ }
130
+
118
131
// FIXME: can this be reworked into a worklist-based algorithm while preserving
119
132
// the depth-first, early bailout traversal?
120
133
LLVM_NODISCARD Value *Negator::visitImpl (Value *V, unsigned Depth) {
@@ -159,11 +172,13 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
159
172
160
173
// In some cases we can give the answer without further recursion.
161
174
switch (I->getOpcode ()) {
162
- case Instruction::Add:
175
+ case Instruction::Add: {
176
+ std::array<Value *, 2 > Ops = getSortedOperandsOfBinOp (I);
163
177
// `inc` is always negatible.
164
- if (match (I-> getOperand ( 1 ) , m_One ()))
165
- return Builder.CreateNot (I-> getOperand ( 0 ) , I->getName () + " .neg" );
178
+ if (match (Ops[ 1 ] , m_One ()))
179
+ return Builder.CreateNot (Ops[ 0 ] , I->getName () + " .neg" );
166
180
break ;
181
+ }
167
182
case Instruction::Xor:
168
183
// `not` is always negatible.
169
184
if (match (I, m_Not (m_Value (X))))
@@ -344,16 +359,18 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
344
359
ConstantExpr::getShl (Constant::getAllOnesValue (Op1C->getType ()), Op1C),
345
360
I->getName () + " .neg" );
346
361
}
347
- case Instruction::Or:
362
+ case Instruction::Or: {
348
363
if (!haveNoCommonBitsSet (I->getOperand (0 ), I->getOperand (1 ), DL, &AC, I,
349
364
&DT))
350
365
return nullptr ; // Don't know how to handle `or` in general.
366
+ std::array<Value *, 2 > Ops = getSortedOperandsOfBinOp (I);
351
367
// `or`/`add` are interchangeable when operands have no common bits set.
352
368
// `inc` is always negatible.
353
- if (match (I-> getOperand ( 1 ) , m_One ()))
354
- return Builder.CreateNot (I-> getOperand ( 0 ) , I->getName () + " .neg" );
369
+ if (match (Ops[ 1 ] , m_One ()))
370
+ return Builder.CreateNot (Ops[ 0 ] , I->getName () + " .neg" );
355
371
// Else, just defer to Instruction::Add handling.
356
372
LLVM_FALLTHROUGH;
373
+ }
357
374
case Instruction::Add: {
358
375
// `add` is negatible if both of its operands are negatible.
359
376
SmallVector<Value *, 2 > NegatedOps, NonNegatedOps;
@@ -383,26 +400,29 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
383
400
return Builder.CreateSub (NegatedOps[0 ], NonNegatedOps[0 ],
384
401
I->getName () + " .neg" );
385
402
}
386
- case Instruction::Xor:
403
+ case Instruction::Xor: {
404
+ std::array<Value *, 2 > Ops = getSortedOperandsOfBinOp (I);
387
405
// `xor` is negatible if one of its operands is invertible.
388
406
// FIXME: InstCombineInverter? But how to connect Inverter and Negator?
389
- if (auto *C = dyn_cast<Constant>(I-> getOperand ( 1 ) )) {
390
- Value *Xor = Builder.CreateXor (I-> getOperand ( 0 ) , ConstantExpr::getNot (C));
407
+ if (auto *C = dyn_cast<Constant>(Ops[ 1 ] )) {
408
+ Value *Xor = Builder.CreateXor (Ops[ 0 ] , ConstantExpr::getNot (C));
391
409
return Builder.CreateAdd (Xor, ConstantInt::get (Xor->getType (), 1 ),
392
410
I->getName () + " .neg" );
393
411
}
394
412
return nullptr ;
413
+ }
395
414
case Instruction::Mul: {
415
+ std::array<Value *, 2 > Ops = getSortedOperandsOfBinOp (I);
396
416
// `mul` is negatible if one of its operands is negatible.
397
417
Value *NegatedOp, *OtherOp;
398
418
// First try the second operand, in case it's a constant it will be best to
399
419
// just invert it instead of sinking the `neg` deeper.
400
- if (Value *NegOp1 = negate (I-> getOperand ( 1 ) , Depth + 1 )) {
420
+ if (Value *NegOp1 = negate (Ops[ 1 ] , Depth + 1 )) {
401
421
NegatedOp = NegOp1;
402
- OtherOp = I-> getOperand ( 0 ) ;
403
- } else if (Value *NegOp0 = negate (I-> getOperand ( 0 ) , Depth + 1 )) {
422
+ OtherOp = Ops[ 0 ] ;
423
+ } else if (Value *NegOp0 = negate (Ops[ 0 ] , Depth + 1 )) {
404
424
NegatedOp = NegOp0;
405
- OtherOp = I-> getOperand ( 1 ) ;
425
+ OtherOp = Ops[ 1 ] ;
406
426
} else
407
427
// Can't negate either of them.
408
428
return nullptr ;
0 commit comments