forked from OSchip/llvm-project
Fix bug in PR454 resolution. Added new test case.
This fixes llvmAsmParser.cpp miscompile by llvm on PowerPC Darwin. llvm-svn: 31053
This commit is contained in:
parent
336d62e99a
commit
b42aef4925
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue