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.
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
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
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
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
--- /dev/null
+; 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
+}