Skip to content

[fix](be) Preserve floating point values in CASE branch selection - #67896

Open
HappenLee wants to merge 1 commit into
apache:masterfrom
HappenLee:fix-case-float-nonfinite
Open

[fix](be) Preserve floating point values in CASE branch selection#67896
HappenLee wants to merge 1 commit into
apache:masterfrom
HappenLee:fix-case-float-nonfinite

Conversation

@HappenLee

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: A non-nullable FLOAT/DOUBLE CASE can return NaN for a finite selected branch when an unselected branch contains Infinity or NaN. For example, with ordinary CASE evaluation, selecting 1, an overflowing multiplication, and 2 over three rows returns NaN, Infinity, NaN instead of 1, Infinity, 2. The same result assembly also loses the sign of selected negative zero.

The result assembly multiplies each branch value by a zero/one mask and adds it to the result. IEEE-754 arithmetic makes 0 * Infinity and 0 * NaN equal NaN. Replace this floating point path with conditional stores so that selected values are copied without arithmetic. This form generates AVX2 masked loads/stores; a ternary assignment can instead become a conditional pointer load that inhibits vectorization.

Add bitwise unit tests, SQL regression tests and a benchmark that directly calls the production result assembly function.

Release note

Fix incorrect FLOAT/DOUBLE CASE results caused by unselected non-finite branch values, and preserve selected negative zero.

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (details below)
    • No need to test or manual test.

    Validation:

    • All 12 new unit tests fail on the original implementation and pass with ASAN after the fix. Coverage includes FLOAT/DOUBLE, uint8_t/uint16_t indices, constant columns, non-finite values, signed zero, subnormal values, vector tails, and 255/257 branches.
    • test_case_float_nonfinite and test_short_circuit_evaluation pass. The original implementation fails the new SQL regression. Golden output was generated and independently verified through short-circuit evaluation using the regression runner.
    • ASAN BE build, clang-format 16, header hygiene, and clang-tidy checks pass.
    • RELEASE benchmarks built with Clang 21.1.8 and -O3 -msse4.2 -mavx2 on Xeon Platinum 8457C cover 42 scenarios. With identical input, a fixed CPU, five repetitions per run and before/after/after/before ordering, median CPU time decreases by approximately 5%–39% (18.5% geometric mean reduction). This measures the result assembly function on this AVX2 machine, including result allocation.
    • Disassembly of all four floating point/index-width specializations in the linked binaries confirms vmaskmovps/pd, replacing floating point multiply/add instructions without fast-math.
  • Behavior changed:

    • No.
    • Yes. Return the selected floating point value without contamination from other branches or loss of negative zero.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: Non-nullable FLOAT/DOUBLE CASE assembles results by multiplying
branch values by zero or one and adding them to a zero-initialized result. An
unselected Infinity or NaN therefore contaminates a finite selected result, and
a selected negative zero loses its sign. For example, a three-row CASE selecting
1, an overflowing multiplication, and 2 returns NaN, Infinity, NaN instead.

Use conditional stores for floating point columns so that only selected values
are copied. This preserves their bits and lets Clang generate AVX2 masked
loads/stores; a ternary source/result load can inhibit vectorization. Keep the
other type paths unchanged. Add bitwise unit tests, SQL regression coverage and
a benchmark that invokes the production result assembly function.

### Release note

Fix incorrect FLOAT/DOUBLE CASE results caused by unselected non-finite branch
values, and preserve selected negative zero.

### Check List (For Author)

- Test: 12 ASAN unit tests; test_case_float_nonfinite and
  test_short_circuit_evaluation regression suites passed. The original code
  fails all 12 new unit tests and the new SQL regression. Golden output was
  generated and verified through short-circuit evaluation using the runner.
  ASAN BE build, clang-format 16, header hygiene and clang-tidy passed.
  RELEASE AVX2 benchmarks on Xeon Platinum 8457C cover 42 scenarios using
  identical input, fixed CPU and repeated before/after/after/before runs;
  median CPU time decreased by 5% to 39%. Inspected all four floating point
  and index-width specializations in the linked binaries for masked SIMD.
- Behavior changed: Yes, return only the selected floating point branch value.
- Does this need documentation: No
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants