Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InstCombine Transform Broken for set[lg]t (cast X to X++), CI #826

Closed
llvmbot opened this issue Nov 2, 2004 · 16 comments
Closed

InstCombine Transform Broken for set[lg]t (cast X to X++), CI #826

llvmbot opened this issue Nov 2, 2004 · 16 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla code-quality

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 2, 2004

Bugzilla Link 454
Resolution FIXED
Resolved on Mar 06, 2010 14:00
Version trunk
OS All
Attachments Assembly test case, IRC Log Describing The Problem
Reporter LLVM Bugzilla Contributor
CC @lattner,@markus-oberhumer

Extended Description

Currently, the instruction combiner is broken when it tries to eliminate a setcc
with a cast and a constant as an argument under a number of constraints:

  1. Only for setgt (>) and setlt (<)
  2. Only when one of the operands is a case and the other is a constant
  3. Only when the cast is to a larger integer type (e.g. sbyte -> int).

The code in question is the switch case starting at InstructionCombining.cpp:2021.

Currently, the optimization has been disabled (leading to performance
degradation of generated code). The disablement was provided by this patch:

http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20041101/020140.html

This bug aims to fix the pessimization by correctly re-enabling the optimization.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 2, 2004

assigned to @lattner

@lattner
Copy link
Collaborator

lattner commented Nov 2, 2004

This testcase may work better:

bool %nada(sbyte %X) {
%Y = cast sbyte %X to uint
%C = setgt uint %Y, 255
ret bool %C
}

Otherwise, instcombine will just delete all of the code. :)

In this case, it should be optimized to:

bool %nada(sbyte %X) {
%C = setlt sbyte %X, 0
ret bool %C
}

-Chris

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

Potential Patch
I've run through this numerous times and can't see anything wrong with it even
though it is substantially the same as the original.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

Test Case
More rigorous test case

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

The "Potential Patch" produces the following xform from the "Test Case". I'd
appreciate it if you could review this and let me know if its okay to commit or
what I did wrong.

bool %lt_signed_to_large_unsigned(sbyte %SB) {
ret bool true
}
bool %lt_signed_to_large_signed(sbyte %SB) {
ret bool true
}
bool %lt_signed_to_large_negative(sbyte %SB) {
ret bool false
}
bool %lt_signed_to_small_unsigned(sbyte %SB) {
%C = setlt sbyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %lt_signed_to_small_signed(sbyte %SB) {
%C = setlt sbyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %lt_signed_to_small_negative(sbyte %SB) {
%C = setlt sbyte %SB, -17 ; [#uses=1]
ret bool %C
}
bool %lt_unsigned_to_large_unsigned(ubyte %SB) {
ret bool true
}
bool %lt_unsigned_to_large_signed(ubyte %SB) {
ret bool true
}
bool %lt_unsigned_to_large_negative(ubyte %SB) {
ret bool false
}
bool %lt_unsigned_to_small_unsigned(ubyte %SB) {
%C = setlt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %lt_unsigned_to_small_signed(ubyte %SB) {
%C = setlt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %lt_unsigned_to_small_negative(ubyte %SB) {
ret bool false
}
bool %gt_signed_to_large_unsigned(sbyte %SB) {
%C = setgt sbyte %SB, -127 ; [#uses=1]
ret bool %C
}
bool %gt_signed_to_large_signed(sbyte %SB) {
ret bool false
}
bool %gt_signed_to_large_negative(sbyte %SB) {
ret bool true
}
bool %gt_signed_to_small_unsigned(sbyte %SB) {
%C = setgt sbyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %gt_signed_to_small_signed(sbyte %SB) {
%C = setgt sbyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %gt_signed_to_small_negative(sbyte %SB) {
%C = setgt sbyte %SB, -17 ; [#uses=1]
ret bool %C
}
bool %gt_unsigned_to_large_unsigned(ubyte %SB) {
ret bool false
}
bool %gt_unsigned_to_large_signed(ubyte %SB) {
ret bool false
}
bool %gt_unsigned_to_large_negative(ubyte %SB) {
ret bool true
}
bool %gt_unsigned_to_small_unsigned(ubyte %SB) {
%C = setgt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %gt_unsigned_to_small_signed(ubyte %SB) {
%C = setgt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}
bool %gt_unsigned_to_small_negative(ubyte %SB) {
ret bool true
}

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

Second Potential Patch

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

Okay, the new patch now delivers:

bool %lt_signed_to_large_unsigned(sbyte %SB) {
ret bool true
}

bool %lt_signed_to_large_signed(sbyte %SB) {
ret bool true
}

bool %lt_signed_to_large_negative(sbyte %SB) {
ret bool false
}

bool %lt_signed_to_small_unsigned(sbyte %SB) {
%Y = cast sbyte %SB to ubyte ; [#uses=1]
%C = setlt ubyte %Y, 17 ; [#uses=1]
ret bool %C
}

bool %lt_signed_to_small_signed(sbyte %SB) {
%C = setlt sbyte %SB, 17 ; [#uses=1]
ret bool %C
}

bool %lt_signed_to_small_negative(sbyte %SB) {
%C = setlt sbyte %SB, -17 ; [#uses=1]
ret bool %C
}

bool %lt_unsigned_to_large_unsigned(ubyte %SB) {
ret bool true
}

bool %lt_unsigned_to_large_signed(ubyte %SB) {
ret bool true
}

bool %lt_unsigned_to_large_negative(ubyte %SB) {
ret bool false
}

bool %lt_unsigned_to_small_unsigned(ubyte %SB) {
%C = setlt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}

bool %lt_unsigned_to_small_signed(ubyte %SB) {
%C = setlt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}

bool %lt_unsigned_to_small_negative(ubyte %SB) {
ret bool false
}

bool %gt_signed_to_large_unsigned(sbyte %SB) {
%Y = cast sbyte %SB to ubyte ; [#uses=1]
%C = setgt ubyte %Y, 129 ; [#uses=1]
ret bool %C
}

bool %gt_signed_to_large_signed(sbyte %SB) {
ret bool false
}

bool %gt_signed_to_large_negative(sbyte %SB) {
ret bool true
}

bool %gt_signed_to_small_unsigned(sbyte %SB) {
%Y = cast sbyte %SB to ubyte ; [#uses=1]
%C = setgt ubyte %Y, 17 ; [#uses=1]
ret bool %C
}

bool %gt_signed_to_small_signed(sbyte %SB) {
%C = setgt sbyte %SB, 17 ; [#uses=1]
ret bool %C
}

bool %gt_signed_to_small_negative(sbyte %SB) {
%C = setgt sbyte %SB, -17 ; [#uses=1]
ret bool %C
}

bool %gt_unsigned_to_large_unsigned(ubyte %SB) {
ret bool false
}

bool %gt_unsigned_to_large_signed(ubyte %SB) {
ret bool false
}

bool %gt_unsigned_to_large_negative(ubyte %SB) {
ret bool true
}

bool %gt_unsigned_to_small_unsigned(ubyte %SB) {
%C = setgt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}

bool %gt_unsigned_to_small_signed(ubyte %SB) {
%C = setgt ubyte %SB, 17 ; [#uses=1]
ret bool %C
}

bool %gt_unsigned_to_small_negative(ubyte %SB) {
ret bool true
}

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

Third Potential Patch
This is the same as the last one but it puts the guts of the Instruction::Cast
case of visitSetCondInst into visitSetCondInstWithCastAndConstant

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

The last patch is currently awaiting results of nightly testing. It will be
committed if it passes.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Nov 28, 2004

@lattner
Copy link
Collaborator

lattner commented Jan 17, 2005

Part of this patch was disabled here:
http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050110/023419.html

It miscompiles the testcase in the commit.

-Chris

@lattner
Copy link
Collaborator

lattner commented Apr 24, 2005

This transform was reimplemented and reenabled here:
http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050418/025735.html

-Chris

@markus-oberhumer
Copy link

I just want to add a short note that the code contains several shifts in the
form "(1ULL << C2->getType()->getPrimitiveSizeInBits())-1;" which might cause
shift overflows.

Maybe it would be a good idea to implement some "uint64_t getHighBit(unsigned
bits)" and "uint64_t generateMask(unsigned bits)" helper functions that
correctly deal with bits == 64. Or these could also made member functions of Type.

@lattner
Copy link
Collaborator

lattner commented Apr 24, 2005

Excellent point, I'll audit these.

Thanks!

-Chris

@lattner
Copy link
Collaborator

lattner commented Apr 24, 2005

Yup, there were bugs. Fixed here:
http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050418/025751.html

Thanks!

-Chris

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 3, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla code-quality
Projects
None yet
Development

No branches or pull requests

3 participants