@@ -128,7 +128,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
128
128
129
129
// FIXME: can this be reworked into a worklist-based algorithm while preserving
130
130
// the depth-first, early bailout traversal?
131
- [[nodiscard]] Value *Negator::visitImpl (Value *V, unsigned Depth) {
131
+ [[nodiscard]] Value *Negator::visitImpl (Value *V, bool IsNSW, unsigned Depth) {
132
132
// -(undef) -> undef.
133
133
if (match (V, m_Undef ()))
134
134
return V;
@@ -237,7 +237,8 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
237
237
// However, only do this either if the old `sub` doesn't stick around, or
238
238
// it was subtracting from a constant. Otherwise, this isn't profitable.
239
239
return Builder.CreateSub (I->getOperand (1 ), I->getOperand (0 ),
240
- I->getName () + " .neg" );
240
+ I->getName () + " .neg" , /* HasNUW */ false ,
241
+ IsNSW && I->hasNoSignedWrap ());
241
242
}
242
243
243
244
// Some other cases, while still don't require recursion,
@@ -302,7 +303,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
302
303
switch (I->getOpcode ()) {
303
304
case Instruction::Freeze: {
304
305
// `freeze` is negatible if its operand is negatible.
305
- Value *NegOp = negate (I->getOperand (0 ), Depth + 1 );
306
+ Value *NegOp = negate (I->getOperand (0 ), IsNSW, Depth + 1 );
306
307
if (!NegOp) // Early return.
307
308
return nullptr ;
308
309
return Builder.CreateFreeze (NegOp, I->getName () + " .neg" );
@@ -313,7 +314,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
313
314
SmallVector<Value *, 4 > NegatedIncomingValues (PHI->getNumOperands ());
314
315
for (auto I : zip (PHI->incoming_values (), NegatedIncomingValues)) {
315
316
if (!(std::get<1 >(I) =
316
- negate (std::get<0 >(I), Depth + 1 ))) // Early return.
317
+ negate (std::get<0 >(I), IsNSW, Depth + 1 ))) // Early return.
317
318
return nullptr ;
318
319
}
319
320
// All incoming values are indeed negatible. Create negated PHI node.
@@ -336,10 +337,10 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
336
337
return NewSelect;
337
338
}
338
339
// `select` is negatible if both hands of `select` are negatible.
339
- Value *NegOp1 = negate (I->getOperand (1 ), Depth + 1 );
340
+ Value *NegOp1 = negate (I->getOperand (1 ), IsNSW, Depth + 1 );
340
341
if (!NegOp1) // Early return.
341
342
return nullptr ;
342
- Value *NegOp2 = negate (I->getOperand (2 ), Depth + 1 );
343
+ Value *NegOp2 = negate (I->getOperand (2 ), IsNSW, Depth + 1 );
343
344
if (!NegOp2)
344
345
return nullptr ;
345
346
// Do preserve the metadata!
@@ -349,10 +350,10 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
349
350
case Instruction::ShuffleVector: {
350
351
// `shufflevector` is negatible if both operands are negatible.
351
352
auto *Shuf = cast<ShuffleVectorInst>(I);
352
- Value *NegOp0 = negate (I->getOperand (0 ), Depth + 1 );
353
+ Value *NegOp0 = negate (I->getOperand (0 ), IsNSW, Depth + 1 );
353
354
if (!NegOp0) // Early return.
354
355
return nullptr ;
355
- Value *NegOp1 = negate (I->getOperand (1 ), Depth + 1 );
356
+ Value *NegOp1 = negate (I->getOperand (1 ), IsNSW, Depth + 1 );
356
357
if (!NegOp1)
357
358
return nullptr ;
358
359
return Builder.CreateShuffleVector (NegOp0, NegOp1, Shuf->getShuffleMask (),
@@ -361,7 +362,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
361
362
case Instruction::ExtractElement: {
362
363
// `extractelement` is negatible if source operand is negatible.
363
364
auto *EEI = cast<ExtractElementInst>(I);
364
- Value *NegVector = negate (EEI->getVectorOperand (), Depth + 1 );
365
+ Value *NegVector = negate (EEI->getVectorOperand (), IsNSW, Depth + 1 );
365
366
if (!NegVector) // Early return.
366
367
return nullptr ;
367
368
return Builder.CreateExtractElement (NegVector, EEI->getIndexOperand (),
@@ -371,34 +372,36 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
371
372
// `insertelement` is negatible if both the source vector and
372
373
// element-to-be-inserted are negatible.
373
374
auto *IEI = cast<InsertElementInst>(I);
374
- Value *NegVector = negate (IEI->getOperand (0 ), Depth + 1 );
375
+ Value *NegVector = negate (IEI->getOperand (0 ), IsNSW, Depth + 1 );
375
376
if (!NegVector) // Early return.
376
377
return nullptr ;
377
- Value *NegNewElt = negate (IEI->getOperand (1 ), Depth + 1 );
378
+ Value *NegNewElt = negate (IEI->getOperand (1 ), IsNSW, Depth + 1 );
378
379
if (!NegNewElt) // Early return.
379
380
return nullptr ;
380
381
return Builder.CreateInsertElement (NegVector, NegNewElt, IEI->getOperand (2 ),
381
382
I->getName () + " .neg" );
382
383
}
383
384
case Instruction::Trunc: {
384
385
// `trunc` is negatible if its operand is negatible.
385
- Value *NegOp = negate (I->getOperand (0 ), Depth + 1 );
386
+ Value *NegOp = negate (I->getOperand (0 ), /* IsNSW */ false , Depth + 1 );
386
387
if (!NegOp) // Early return.
387
388
return nullptr ;
388
389
return Builder.CreateTrunc (NegOp, I->getType (), I->getName () + " .neg" );
389
390
}
390
391
case Instruction::Shl: {
391
392
// `shl` is negatible if the first operand is negatible.
392
- if (Value *NegOp0 = negate (I->getOperand (0 ), Depth + 1 ))
393
- return Builder.CreateShl (NegOp0, I->getOperand (1 ), I->getName () + " .neg" );
393
+ IsNSW &= I->hasNoSignedWrap ();
394
+ if (Value *NegOp0 = negate (I->getOperand (0 ), IsNSW, Depth + 1 ))
395
+ return Builder.CreateShl (NegOp0, I->getOperand (1 ), I->getName () + " .neg" ,
396
+ /* HasNUW */ false , IsNSW);
394
397
// Otherwise, `shl %x, C` can be interpreted as `mul %x, 1<<C`.
395
398
auto *Op1C = dyn_cast<Constant>(I->getOperand (1 ));
396
399
if (!Op1C || !IsTrulyNegation)
397
400
return nullptr ;
398
401
return Builder.CreateMul (
399
402
I->getOperand (0 ),
400
403
ConstantExpr::getShl (Constant::getAllOnesValue (Op1C->getType ()), Op1C),
401
- I->getName () + " .neg" );
404
+ I->getName () + " .neg" , /* HasNUW */ false , IsNSW );
402
405
}
403
406
case Instruction::Or: {
404
407
if (!haveNoCommonBitsSet (I->getOperand (0 ), I->getOperand (1 ), DL, &AC, I,
@@ -417,7 +420,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
417
420
SmallVector<Value *, 2 > NegatedOps, NonNegatedOps;
418
421
for (Value *Op : I->operands ()) {
419
422
// Can we sink the negation into this operand?
420
- if (Value *NegOp = negate (Op, Depth + 1 )) {
423
+ if (Value *NegOp = negate (Op, /* IsNSW */ false , Depth + 1 )) {
421
424
NegatedOps.emplace_back (NegOp); // Successfully negated operand!
422
425
continue ;
423
426
}
@@ -458,16 +461,17 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
458
461
Value *NegatedOp, *OtherOp;
459
462
// First try the second operand, in case it's a constant it will be best to
460
463
// just invert it instead of sinking the `neg` deeper.
461
- if (Value *NegOp1 = negate (Ops[1 ], Depth + 1 )) {
464
+ if (Value *NegOp1 = negate (Ops[1 ], /* IsNSW */ false , Depth + 1 )) {
462
465
NegatedOp = NegOp1;
463
466
OtherOp = Ops[0 ];
464
- } else if (Value *NegOp0 = negate (Ops[0 ], Depth + 1 )) {
467
+ } else if (Value *NegOp0 = negate (Ops[0 ], /* IsNSW */ false , Depth + 1 )) {
465
468
NegatedOp = NegOp0;
466
469
OtherOp = Ops[1 ];
467
470
} else
468
471
// Can't negate either of them.
469
472
return nullptr ;
470
- return Builder.CreateMul (NegatedOp, OtherOp, I->getName () + " .neg" );
473
+ return Builder.CreateMul (NegatedOp, OtherOp, I->getName () + " .neg" ,
474
+ /* HasNUW */ false , IsNSW && I->hasNoSignedWrap ());
471
475
}
472
476
default :
473
477
return nullptr ; // Don't know, likely not negatible for free.
@@ -476,7 +480,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
476
480
llvm_unreachable (" Can't get here. We always return from switch." );
477
481
}
478
482
479
- [[nodiscard]] Value *Negator::negate (Value *V, unsigned Depth) {
483
+ [[nodiscard]] Value *Negator::negate (Value *V, bool IsNSW, unsigned Depth) {
480
484
NegatorMaxDepthVisited.updateMax (Depth);
481
485
++NegatorNumValuesVisited;
482
486
@@ -506,15 +510,16 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
506
510
#endif
507
511
508
512
// No luck. Try negating it for real.
509
- Value *NegatedV = visitImpl (V, Depth);
513
+ Value *NegatedV = visitImpl (V, IsNSW, Depth);
510
514
// And cache the (real) result for the future.
511
515
NegationsCache[V] = NegatedV;
512
516
513
517
return NegatedV;
514
518
}
515
519
516
- [[nodiscard]] std::optional<Negator::Result> Negator::run (Value *Root) {
517
- Value *Negated = negate (Root, /* Depth=*/ 0 );
520
+ [[nodiscard]] std::optional<Negator::Result> Negator::run (Value *Root,
521
+ bool IsNSW) {
522
+ Value *Negated = negate (Root, IsNSW, /* Depth=*/ 0 );
518
523
if (!Negated) {
519
524
// We must cleanup newly-inserted instructions, to avoid any potential
520
525
// endless combine looping.
@@ -525,7 +530,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
525
530
return std::make_pair (ArrayRef<Instruction *>(NewInstructions), Negated);
526
531
}
527
532
528
- [[nodiscard]] Value *Negator::Negate (bool LHSIsZero, Value *Root,
533
+ [[nodiscard]] Value *Negator::Negate (bool LHSIsZero, bool IsNSW, Value *Root,
529
534
InstCombinerImpl &IC) {
530
535
++NegatorTotalNegationsAttempted;
531
536
LLVM_DEBUG (dbgs () << " Negator: attempting to sink negation into " << *Root
@@ -536,7 +541,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
536
541
537
542
Negator N (Root->getContext (), IC.getDataLayout (), IC.getAssumptionCache (),
538
543
IC.getDominatorTree (), LHSIsZero);
539
- std::optional<Result> Res = N.run (Root);
544
+ std::optional<Result> Res = N.run (Root, IsNSW );
540
545
if (!Res) { // Negation failed.
541
546
LLVM_DEBUG (dbgs () << " Negator: failed to sink negation into " << *Root
542
547
<< " \n " );
0 commit comments