Fix bug in PR454 resolution. Added new test case.
authorDevang Patel <dpatel@apple.com>
Thu, 19 Oct 2006 18:54:08 +0000 (18:54 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 19 Oct 2006 18:54:08 +0000 (18:54 +0000)
This fixes llvmAsmParser.cpp miscompile by llvm on PowerPC Darwin.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31053 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll [new file with mode: 0644]

index f0961de52743d90547eb64b842764213670b71a4..9ebb5305b6f6163d4f93d610fbe320b79af6c921 100644 (file)
@@ -4785,7 +4785,21 @@ Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) {
     Constant *Res = ConstantExpr::getCast(CI, SrcTy);
 
     if (ConstantExpr::getCast(Res, DestTy) == CI) {
-      RHSCIOp = Res;
+      // Make sure that src sign and dest sign match. For example,
+      //
+      // %A = cast short %X to uint
+      // %B = setgt uint %A, 1330
+      //
+      // It is incorrect to transformt this into 
+      //
+      // %B = setgt short %X, 1330 
+      // 
+      // because %A may have negative value. 
+      // However, it is OK if SrcTy is bool. See cast-set.ll testcase.
+      if (isSignSrc == isSignDest || SrcTy == Type::BoolTy)
+        RHSCIOp = Res;
+      else
+        return 0;
     } else {
       // If the value cannot be represented in the shorter type, we cannot emit
       // a simple comparison.
index a4bf7a7a01d2443e4b94ea8e0287649f35c9a3e9..75e1ac663fa140b4a6f1044158144f592e7bff44 100644 (file)
@@ -31,12 +31,6 @@ bool %lt_signed_to_large_negative(sbyte %SB) {
   ret bool %C
 }
 
-bool %lt_signed_to_small_unsigned(sbyte %SB) {
-  %Y = cast sbyte %SB to uint          ; <uint> [#uses=1]
-  %C = setlt uint %Y, 17               ; <bool> [#uses=1]
-  ret bool %C
-}
-
 bool %lt_signed_to_small_signed(sbyte %SB) {
   %Y = cast sbyte %SB to int
   %C = setlt int %Y, 17
@@ -73,12 +67,6 @@ bool %lt_unsigned_to_small_unsigned(ubyte %SB) {
   ret bool %C
 }
 
-bool %lt_unsigned_to_small_signed(ubyte %SB) {
-  %Y = cast ubyte %SB to int
-  %C = setlt int %Y, 17
-  ret bool %C
-}
-
 bool %lt_unsigned_to_small_negative(ubyte %SB) {
   %Y = cast ubyte %SB to int
   %C = setlt int %Y, -17
@@ -103,12 +91,6 @@ bool %gt_signed_to_large_negative(sbyte %SB) {
   ret bool %C
 }
 
-bool %gt_signed_to_small_unsigned(sbyte %SB) {
-  %Y = cast sbyte %SB to uint          ; <uint> [#uses=1]
-  %C = setgt uint %Y, 17               ; <bool> [#uses=1]
-  ret bool %C
-}
-
 bool %gt_signed_to_small_signed(sbyte %SB) {
   %Y = cast sbyte %SB to int
   %C = setgt int %Y, 17
@@ -145,12 +127,6 @@ bool %gt_unsigned_to_small_unsigned(ubyte %SB) {
   ret bool %C
 }
 
-bool %gt_unsigned_to_small_signed(ubyte %SB) {
-  %Y = cast ubyte %SB to int
-  %C = setgt int %Y, 17
-  ret bool %C
-}
-
 bool %gt_unsigned_to_small_negative(ubyte %SB) {
   %Y = cast ubyte %SB to int
   %C = setgt int %Y, -17
diff --git a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll
new file mode 100644 (file)
index 0000000..e35c366
--- /dev/null
@@ -0,0 +1,8 @@
+; This test case is reduced from llvmAsmParser.cpp
+; The optimizer should not remove the cast here.
+; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | grep 'cast.*int'
+bool %test(short %X) {
+%A = cast short %X to uint
+%B = setgt uint %A, 1330
+ret bool %B
+}