if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
+ // X - (0 - Y) -> X if the second sub is NUW.
+ // If Y != 0, 0 - Y is a poison value.
+ // If Y == 0, 0 - Y simplifies to 0.
+ if (BinaryOperator::isNeg(Op1)) {
+ if (const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
+ assert(BO->getOpcode() == Instruction::Sub &&
+ "Expected a subtraction operator!");
+ if (BO->hasNoUnsignedWrap())
+ return Op0;
+ }
+ }
+
// (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
// For example, (X + Y) - Y -> X; (Y + X) - Y -> X
Value *X = nullptr, *Y = nullptr, *Z = Op1;
ret i64 %e2
; CHECK: ret i64 %e
}
+
+define i32 @sub_neg_nuw(i32 %x, i32 %y) {
+; CHECK-LABEL: @sub_neg_nuw(
+ %neg = sub nuw i32 0, %y
+ %sub = sub i32 %x, %neg
+ ret i32 %sub
+; CHECK: ret i32 %x
+}