[llvm-commits] [llvm] r145316 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCompares.cpp test/Transforms/InstCombine/overflow.ll

Eli Friedman eli.friedman at gmail.com
Mon Nov 28 15:32:19 PST 2011


Author: efriedma
Date: Mon Nov 28 17:32:19 2011
New Revision: 145316

URL: http://llvm.org/viewvc/llvm-project?rev=145316&view=rev
Log:
Add a missing safety check to ProcessUGT_ADDCST_ADD.  Fixes PR11438.


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/overflow.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=145316&r1=145315&r2=145316&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Mon Nov 28 17:32:19 2011
@@ -1657,6 +1657,14 @@
       CI1->getValue() != APInt::getLowBitsSet(CI1->getBitWidth(), NewWidth))
     return 0;
 
+  // This is only really a signed overflow check if the inputs have been
+  // sign-extended; check for that condition. For example, if CI2 is 2^31 and
+  // the operands of the add are 64 bits wide, we need at least 33 sign bits.
+  unsigned NeededSignBits = CI1->getBitWidth() - NewWidth + 1;
+  if (IC.ComputeNumSignBits(A) < NeededSignBits ||
+      IC.ComputeNumSignBits(B) < NeededSignBits)
+    return 0;
+
   // In order to replace the original add with a narrower
   // llvm.sadd.with.overflow, the only uses allowed are the add-with-constant
   // and truncates that discard the high bits of the add.  Verify that this is

Modified: llvm/trunk/test/Transforms/InstCombine/overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/overflow.ll?rev=145316&r1=145315&r2=145316&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/overflow.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/overflow.ll Mon Nov 28 17:32:19 2011
@@ -130,4 +130,26 @@
   ret i64 %Q
 }
 
+; CHECK: @test8
+; PR11438
+; This is @test1, but the operands are not sign-extended.  Make sure
+; we don't transform this case.
+define i32 @test8(i64 %a, i64 %b) nounwind ssp {
+entry:
+; CHECK-NOT: llvm.sadd
+; CHECK: add i64 %a, %b
+; CHECK-NOT: llvm.sadd
+; CHECK: ret
+  %add = add i64 %a, %b
+  %add.off = add i64 %add, 2147483648
+  %0 = icmp ugt i64 %add.off, 4294967295
+  br i1 %0, label %if.then, label %if.end
 
+if.then:
+  tail call void @throwAnExceptionOrWhatever() nounwind
+  br label %if.end
+
+if.end:
+  %conv9 = trunc i64 %add to i32
+  ret i32 %conv9
+}





More information about the llvm-commits mailing list