-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Suboptimal Shifting Codegen #12285
Copy link
Copy link
Open
Labels
backend-llvmThe LLVM backend outputs an LLVM IR Module.The LLVM backend outputs an LLVM IR Module.contributor friendlyThis issue is limited in scope and/or knowledge of Zig internals.This issue is limited in scope and/or knowledge of Zig internals.enhancementSolving this issue will likely involve adding new logic or components to the codebase.Solving this issue will likely involve adding new logic or components to the codebase.frontendTokenization, parsing, AstGen, Sema, and Liveness.Tokenization, parsing, AstGen, Sema, and Liveness.optimization
Milestone
Metadata
Metadata
Assignees
Labels
backend-llvmThe LLVM backend outputs an LLVM IR Module.The LLVM backend outputs an LLVM IR Module.contributor friendlyThis issue is limited in scope and/or knowledge of Zig internals.This issue is limited in scope and/or knowledge of Zig internals.enhancementSolving this issue will likely involve adding new logic or components to the codebase.Solving this issue will likely involve adding new logic or components to the codebase.frontendTokenization, parsing, AstGen, Sema, and Liveness.Tokenization, parsing, AstGen, Sema, and Liveness.optimization
Zig Version: 0.10.0-dev.3313+cff5d9c80
I was experimenting with how Zig generates code with oddly sized integers with regards to shifting instructions and found a case where I think it is generating poor quality code (unless I am missing some key factor here). For instance this code:
As far as I know
@shlExactmakes it UB to shift 1 bits out of the range (au15in this case), and@intCastmakes it UB to cast from a value outside that range as well. Knowing this I'd expect it simply to generate a mov for the constant 1 and a shift, but instead I get this:To me these
andoperations are pointless due to the previously mentioned constraints and I am not sure why they are appearing here. Interestingly as well, when I change theu15to au16I get a different result:That looks more like what I'd expect, other than the strange
andon the shift amount still. Perhaps this difference is due to there being one technically invalid shift value for theu15which can fit in au4(the value 15) which it feels the need to mask against, but again that doesn't seem like it'd matter since it's supposed to be undefined behavior anyways.Also perhaps unsurprisingly when working with more typical integers things work fine:
Resulting in:
Edit:
I did find that if you add an assert in to try and inform the compiler of the value limitations this fixes the and-ing of the input at least, so maybe the solution can be implemented in a similar way: