From: Devang Patel Date: Thu, 19 Oct 2006 18:54:08 +0000 (+0000) Subject: Fix bug in PR454 resolution. Added new test case. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6ce890b6ec6ee7823a225608967a94cc6bdbd06e;p=oota-llvm.git Fix bug in PR454 resolution. Added new test case. 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 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index f0961de5274..9ebb5305b6f 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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. diff --git a/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll b/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll index a4bf7a7a01d..75e1ac663fa 100644 --- a/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll +++ b/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll @@ -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 ; [#uses=1] - %C = setlt uint %Y, 17 ; [#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 ; [#uses=1] - %C = setgt uint %Y, 17 ; [#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 index 00000000000..e35c36694fe --- /dev/null +++ b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll @@ -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 +}