Repository navigation
Conversation
LowerFP_TO_INT64 and legalizeFPTOI split a float into 32-bit halves with hif = floor(tf * 2^-32) and lof = tf - hif * 2^32, where tf is trunc(val). The truncation only matters when val can be a negative non-integer, because the split floors. For a nonnegative val, floor(val * 2^-32) already equals floor(trunc(val) * 2^-32), and the fraction left in lof is dropped by the fptoui of the low half. So use |val| instead of trunc(val) when: - the input is signed f32, which already converts the magnitude and restores the sign afterwards; - the conversion is unsigned, where inputs at or below -1 are poison and inputs in (-1, 0) convert to 0, the same as their absolute value. Signed f64 splits val itself, so it still truncates unless val is already an integer (the result of a rounding operation or an int-to-fp conversion) or cannot be ordered less than zero. The fabs folds into a source modifier. On targets without v_trunc_f64, skipping the truncation also avoids its expansion, which happens during legalization before the generic ftrunc combine can fold it. The change is applied to both SelectionDAG and GlobalISel. llvm#231060 folded fp_to_int(ftrunc(x)) generically and noted that the AMDGPU f32-to-i64 tests did not change because this lowering emits its own ftrunc. This patch removes that ftrunc where it is not needed. Across the updated autogenerated tests, 141 function/target pairs get shorter and 18 get longer. For example, fp_to_sint.ll on gfx1100 goes from 22/34/57 to 21/29/51 instructions for scalar/v2/v4. All 18 longer ones are uniform (SGPR) inputs on targets before gfx10, where VOP3 can read only one scalar operand, so the folded |src| modifier needs extra v_mov copies (at most 4 instructions, e.g. fp_to_sint_v4i64 on SI/VI). Related open PR llvm#239233 folds floor into unsigned FP-to-int conversions and updates several of the same tests (bf16.ll, fp_to_sint.ll, fp_to_uint.ll, fptosi-sat-scalar.ll, fptoui-sat-*.ll, lround.ll, lrint.ll and the GlobalISel bf16 tests); whichever lands second needs to regenerate them. Open PR llvm#118831 moves FP/int lowering into generic TargetLowering; this change only removes a redundant operation in the AMDGPU expansion and does not move or share the lowering implementation. Regenerate existing CHECKs and update the hand-written checks in fp_to_uint.f64.ll. No test functions or IR inputs are added or changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LowerFP_TO_INT64andlegalizeFPTOIsplit a float into 32-bit halves:This only matters when
valis a negative non-integer.For nonnegative
val,floor(val * 2^-32) == floor(trunc(val) * 2^-32), and the fraction left inlofis dropped by thefptouiof the low half.Instead we could do: use
abs(val)in place oftrunc(val)for signed non-integer or unsigned.Both GlobalISel and SelectionDAG are modified.
Relevant PRs:
#239233 and #231060