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

Instruction Combining misoptimization #1871

Closed
llvmbot opened this issue Jun 5, 2007 · 4 comments
Closed

Instruction Combining misoptimization #1871

llvmbot opened this issue Jun 5, 2007 · 4 comments
Labels
bugzilla Issues migrated from bugzilla

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 5, 2007

Bugzilla Link 1499
Resolution FIXED
Resolved on Feb 22, 2010 12:50
Version 2.0
OS Linux
Attachments bugpoint-tooptimize.bc
Reporter LLVM Bugzilla Contributor

Extended Description

Instruction Combining is wrongly optimizing the following code:

    %tmp30 = load i64* %tmp10               ; <i64> [#uses=1]
    %.cast = zext i32 63 to i64             ; <i64> [#uses=1]
    %tmp31 = ashr i64 %tmp30, %.cast                ; <i64> [#uses=1]
    %tmp3132 = trunc i64 %tmp31 to i32              ; <i32> [#uses=1]
    %tmp33 = or i32 %tmp3132, 1             ; <i32> [#uses=1]
    store i32 %tmp33, i32* %tmp9
    %tmp34 = load i32* %tmp9                ; <i32> [#uses=1]
    store i32 %tmp34, i32* %retval
    br label %return.exitStub

to
store i32 -1, i32* %tmp9
store i32 -1, i32* %retval
ret void

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jun 6, 2007

The problematic function (ffmpeg/libavutil/rational.h):

/**

  • Rational number num/den.
    */
    typedef struct AVRational{
    int num; ///< numerator
    int den; ///< denominator
    } AVRational;

/**

  • Compare two rationals.

  • @​param a first rational

  • @​param b second rational

  • @​return 0 if a==b, 1 if a>b and -1 if a<b.
    */
    static inline int av_cmp_q(AVRational a, AVRational b){
    const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den;

    if(tmp) return (tmp>>63)Fixing Rust build #1;
    else return 0;
    }


I think the comment is wrong. This function returns 0 if a==b, 1 if a>b and
-0x7FFFFFFF if a<b.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jun 6, 2007

fix
Arithmetic left shift is not the inverse operation of arithmetic right shift.
The arithmetic left shift can result in overflow. So, we should preserve the
sign bit beyond making the arithmetic left shift.

@lattner
Copy link
Collaborator

lattner commented Jun 6, 2007

The patch is close, but not quite right. The sign bit definitely does need to be demanded in some
cases, but only in those cases where one of the shifted in bits is used. For example, consider:

%Y = ashr i8 %X, 3

If we demand (f.e.) the low two bits from Y, then the input sign bit is not needed. However, if any of
the top three bits are demanded, then the input sign bit is demanded.

So basically, in that code, if any of the "high bits" are demanded, you should set the sign bit as
demanded. If none of the high bits are demanded, the sign bit should not be demanded.

Thanks again for investigating this Lauro!

-Chris

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 3, 2021
kitano-metro pushed a commit to RIKEN-RCCS/llvm-project that referenced this issue Mar 14, 2023
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
Projects
None yet
Development

No branches or pull requests

2 participants