x64: Mask shift amounts for small types#4752
x64: Mask shift amounts for small types#4752jameysharp merged 5 commits intobytecodealliance:mainfrom
Conversation
Subscribe to Label ActionDetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "isle"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
|
I think this is also going to invalidate all the fuzzer issues that were reported today, since it changes the input format for the fuzzer, not sure how good OSS-Fuzz is with these situations. |
ab87ae9 to
94bd34b
Compare
|
You're right, Afonso. Could you remove the function-generator changes from this PR for now while we sort out all those issues? |
They are fixed. But we had a bunch of fuzzgen issues come in, and we don't want to accidentaly mark them as fixed
|
The rustfmt CI failure looks like a transient network issue. Let's re-run it after the rest of the jobs complete. |
| if let Some(c) = inputs.constant { | ||
| let mask = 1_u64.checked_shl(ty.bits()).map_or(u64::MAX, |x| x - 1); | ||
| return Imm8Gpr::new(Imm8Reg::Imm8 { | ||
| imm: (c & mask) as u8, | ||
| }) | ||
| .unwrap(); | ||
| } | ||
|
|
||
| Imm8Gpr::new(Imm8Reg::Reg { | ||
| reg: self.put_in_regs(val).regs()[0], | ||
| }) | ||
| .unwrap() |
There was a problem hiding this comment.
I want to see if I understand why this PR fixes this issue. Could you confirm or correct my interpretation?
It looks like there are two bugs in put_masked_in_imm8_gpr, and I gather that these bugs aren't present in the similar-looking ISLE rules.
If the shift amount is not defined by an iconst instruction, then this function doesn't mask it at all...? The only thing it does is, if the shift amount needs two registers because it's an i128, then it only takes the lower 64-bit register.
If it is a constant, then it's masked by (1 << ty.bits()) - 1. So for an 8-bit LHS, the shift amount is used modulo 256, but it's actually supposed to be modulo 8. For a 64-bit LHS the shift amount is effectively not masked at all. By contrast, the shift_mask function just returns ty.lane_bits() - 1 so it gets this right. (And also handles vector types correctly, I guess?)
I guess the reason these bugs weren't obvious sooner is that wasm only uses i32 and i64 types, and x86 already masks 32-bit and 64-bit shift amounts to 5 and 6 bits, respectively. But narrower 8-bit and 16-bit shifts are also masked to 5 bits on x86, so those were wrong.
Now that I think I understand this, I'm wondering how hard it is in ISLE to avoid emitting the and instruction when the type is i32 or i64.
There was a problem hiding this comment.
If the shift amount is not defined by an iconst instruction, then this function doesn't mask it at all...?
Yes, the source of the issue I was trying to fix was exactly this.
It looks like there are two bugs in put_masked_in_imm8_gpr, and I gather that these bugs aren't present in the similar-looking ISLE rules.
Wow! I was just trying to fix the unmasked non const one, didn't actually realize that the const case didn't do the right thing either!
We should probably add some shift_imm test cases as well.
Now that I think I understand this, I'm wondering how hard it is in ISLE to avoid emitting the and instruction when the type is i32 or i64.
I think that's a good improvement, i'll push it soon.
There was a problem hiding this comment.
And it turns out the const case was also wrong. Great Catch!
Now that `put_masked_in_imm8_gpr` works properly we can simplify rotl/rotr
|
We now use the general case that is using These were the only uses of |
|
Very nice work! Good catch on noticing that |
This was reported by @bjorn3 in https://github.com/bjorn3/rustc_codegen_cranelift/pull/1268#issuecomment-1223916783 when we tried to remove the explicit shift amount masking done by
cg_clif.As a consequence of this fix, #4699 is also fixed, which is nice!
This PR also does some other housekeeping:
i128shifts in the fuzzeri128-shifts-small-types.clifruntests and moves them toi128-shifts.clifi128one)ishl/sshr/ushrFixes: #4699
cc: @elliottt