[InstCombine] restrict no-wrap propagation for i1/i2 to avoid miscompiles
authorSanjay Patel <spatel@rotateright.com>
Wed, 18 Jan 2023 15:26:18 +0000 (10:26 -0500)
committerSanjay Patel <spatel@rotateright.com>
Wed, 18 Jan 2023 15:32:12 +0000 (10:32 -0500)
This transform was added with 68c197f07eeae71b9b7,
and the post-commit review noted the potential
for miscompiles at narrow bitwidths.

I'm not sure how to expose the i1 nuw bug because we
already simplify that, but other cases show that
there are missing transforms to add in follow-up
patches.

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/sub.ll

index f4393d6..b68efc9 100644 (file)
@@ -2379,9 +2379,9 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
     auto *OBO0 = cast<OverflowingBinaryOperator>(Op0);
     auto *OBO1 = cast<OverflowingBinaryOperator>(Op1);
     bool PropagateNSW = I.hasNoSignedWrap() && OBO0->hasNoSignedWrap() &&
-                        OBO1->hasNoSignedWrap();
+                        OBO1->hasNoSignedWrap() && BitWidth > 2;
     bool PropagateNUW = I.hasNoUnsignedWrap() && OBO0->hasNoUnsignedWrap() &&
-                        OBO1->hasNoUnsignedWrap();
+                        OBO1->hasNoUnsignedWrap() && BitWidth > 1;
     Value *Add = Builder.CreateAdd(X, Y, "add", PropagateNUW, PropagateNSW);
     Value *Sub = Builder.CreateSub(X, Y, "sub", PropagateNUW, PropagateNSW);
     Value *Mul = Builder.CreateMul(Add, Sub, "", PropagateNUW, PropagateNSW);
index 155c3af..96a527e 100644 (file)
@@ -2489,13 +2489,14 @@ define i1 @diff_of_squares_nuw_i1(i1 %x, i1 %y) {
   ret i1 %r
 }
 
-; FIXME: It is not correct to propagate nsw.
+; It is not correct to propagate nsw.
+; TODO: This should reduce more.
 
 define i2 @diff_of_squares_nsw_i2(i2 %x, i2 %y) {
 ; CHECK-LABEL: @diff_of_squares_nsw_i2(
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i2 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i2 [[X]], [[Y]]
-; CHECK-NEXT:    [[R:%.*]] = mul nsw i2 [[ADD]], [[SUB]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i2 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub i2 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = mul i2 [[ADD]], [[SUB]]
 ; CHECK-NEXT:    ret i2 [[R]]
 ;
   %x2 = mul nsw i2 %x, %x