Allow instcombine to combine "sext(a) >u const" to "a >u trunc(const)".

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91631 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2009-12-17 22:42:29 +00:00
parent aad0d52c5b
commit b17cb06c35
3 changed files with 42 additions and 24 deletions

View File

@ -7299,19 +7299,17 @@ Instruction *InstCombiner::visitICmpInstWithCastAndCast(ICmpInst &ICI) {
// If the re-extended constant didn't change...
if (Res2 == CI) {
// Make sure that sign of the Cmp and the sign of the Cast are the same.
// For example, we might have:
// %A = sext i16 %X to i32
// %B = icmp ugt i32 %A, 1330
// It is incorrect to transform this into
// %B = icmp ugt i16 %X, 1330
// because %A may have negative value.
//
// However, we allow this when the compare is EQ/NE, because they are
// signless.
if (isSignedExt == isSignedCmp || ICI.isEquality())
// Deal with equality cases early.
if (ICI.isEquality())
return new ICmpInst(ICI.getPredicate(), LHSCIOp, Res1);
return 0;
// A signed comparison of sign extended values simplifies into a
// signed comparison.
if (isSignedExt && isSignedCmp)
return new ICmpInst(ICI.getPredicate(), LHSCIOp, Res1);
// The other three cases all fold into an unsigned comparison.
return new ICmpInst(ICI.getUnsignedPredicate(), LHSCIOp, Res1);
}
// The re-extended constant changed so the constant cannot be represented

View File

@ -33,6 +33,14 @@ define i1 @lt_signed_to_large_negative(i8 %SB) {
; CHECK: ret i1 false
}
define i1 @lt_signed_to_small_unsigned(i8 %SB) {
%Y = sext i8 %SB to i32
%C = icmp ult i32 %Y, 17
ret i1 %C
; CHECK: %C = icmp ult i8 %SB, 17
; CHECK: ret i1 %C
}
define i1 @lt_signed_to_small_signed(i8 %SB) {
%Y = sext i8 %SB to i32 ; <i32> [#uses=1]
%C = icmp slt i32 %Y, 17 ; <i1> [#uses=1]
@ -77,6 +85,14 @@ define i1 @lt_unsigned_to_small_unsigned(i8 %SB) {
; CHECK: ret i1 %C
}
define i1 @lt_unsigned_to_small_signed(i8 %SB) {
%Y = zext i8 %SB to i32
%C = icmp slt i32 %Y, 17
ret i1 %C
; CHECK: %C = icmp ult i8 %SB, 17
; CHECK: ret i1 %C
}
define i1 @lt_unsigned_to_small_negative(i8 %SB) {
%Y = zext i8 %SB to i32 ; <i32> [#uses=1]
%C = icmp slt i32 %Y, -17 ; <i1> [#uses=1]
@ -106,6 +122,14 @@ define i1 @gt_signed_to_large_negative(i8 %SB) {
; CHECK: ret i1 true
}
define i1 @gt_signed_to_small_unsigned(i8 %SB) {
%Y = sext i8 %SB to i32
%C = icmp ugt i32 %Y, 17
ret i1 %C
; CHECK: %C = icmp ugt i8 %SB, 17
; CHECK: ret i1 %C
}
define i1 @gt_signed_to_small_signed(i8 %SB) {
%Y = sext i8 %SB to i32 ; <i32> [#uses=1]
%C = icmp sgt i32 %Y, 17 ; <i1> [#uses=1]
@ -151,6 +175,14 @@ define i1 @gt_unsigned_to_small_unsigned(i8 %SB) {
; CHECK: ret i1 %C
}
define i1 @gt_unsigned_to_small_signed(i8 %SB) {
%Y = zext i8 %SB to i32
%C = icmp sgt i32 %Y, 17
ret i1 %C
; CHECK: %C = icmp ugt i8 %SB, 17
; CHECK: ret i1 %C
}
define i1 @gt_unsigned_to_small_negative(i8 %SB) {
%Y = zext i8 %SB to i32 ; <i32> [#uses=1]
%C = icmp sgt i32 %Y, -17 ; <i1> [#uses=1]

View File

@ -1,12 +0,0 @@
; This test case is reduced from llvmAsmParser.cpp
; The optimizer should not remove the cast here.
; RUN: opt < %s -instcombine -S | \
; RUN: grep sext.*i32
define i1 @test(i16 %X) {
%A = sext i16 %X to i32 ; <i32> [#uses=1]
%B = icmp ugt i32 %A, 1330 ; <i1> [#uses=1]
ret i1 %B
}