Skip to content

Unnecessary add emitted for repeated multiplication #75413

Open

Description

@SkiFoD

Description

Noted during work with #74020 , that a series of multiplications generates unnecessary operations. Here is the example
I played with the code for a little bit and figured out that GT_MUL nodes were being optimized, but if GT_MUL op had the right child as a value of power of 2, then the operation converted into GT_LSH (here is the code).
So if we have a series of multiplications by 2 (for simplicity) as an example above, then we end up with a series of GT_LSH operations.
I asume that we can fold the series into one GT_LSH operation with a proper right hand value.

Reproduction Steps

Use snipets like this:

public int T(int u1) {
        return u1*2*2*2*2;
    }

Expected behavior

public int T(int u1) {
        return u1*2*2*2*2;
    }

Generates:

G_M63441_IG02:
       mov      eax, ecx
       shl      eax, 4

Actual behavior

public int T(int u1) {
        return u1*2*2*2*2;
    }

Generates:

C.T(Int32)
    L0000: add edx, edx
    L0002: add edx, edx
    L0004: lea eax, [rdx+rdx]
    L0007: add eax, eax
    L0009: ret

category:cq
theme:basic-cq
skill-level:beginner
cost:small
impact:small

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 11, 2022
  2. ghost added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Sep 11, 2022
  3. added this to the 8.0.0 milestone on Sep 12, 2022
  4. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 12, 2022
  5. GSPP commented on Oct 4, 2022

    @GSPP

    Hm, I might have posted my annotation to the wrong place (I'm not too familiar with the GitHub code review system). Repeating it here:

    SkiFoD@e248d75#diff-5b83397bbbdd17bb9457998b520fdaaa474d165390985b66f32371561b6d0bacR12766

    mul->gtOp2->AsIntConCommon()->SetIntegralValue(root_val + child_val);
    

    Is it possible that this computation would overflow? It could overflow like 30+30 > 32. But could this also cause undefined behavior in the C code of the JIT when computing int.MaxValue + int.MaxValue? Is such a large shift amount possible?

  6. SkiFoD commented on Oct 5, 2022

    @SkiFoD
    ContributorAuthor

    Hm, I might have posted my annotation to the wrong place (I'm not too familiar with the GitHub code review system). Repeating it here:

    SkiFoD@e248d75#diff-5b83397bbbdd17bb9457998b520fdaaa474d165390985b66f32371561b6d0bacR12766

    mul->gtOp2->AsIntConCommon()->SetIntegralValue(root_val + child_val);
    

    Is it possible that this computation would overflow? It could overflow like 30+30 > 32. But could this also cause undefined behavior in the C code of the JIT when computing int.MaxValue + int.MaxValue? Is such a large shift amount possible?

    Your concerns are correct. I'm not sure if such a situation possible so the op tree would have int.max shifts. I think we need an opinion of someone from the team.

  7. danmoseley commented on Dec 21, 2022

    @danmoseley
    Contributor

    @EgorBo I think there is a question above.

  8. removed their assignment
    on Mar 27, 2023
  9. modified the milestones: 8.0.0, Future on Mar 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions