Repository navigation
GH-55613: [C++][Gandiva] Fix wrong results for negative integer constants - #55607
dmitry-chirkov-dremio wants to merge 2 commits into
Conversation
|
Thanks for opening a pull request! This pull request has been automatically converted to a draft because its title doesn't match Arrow's required format. If this is not a minor PR, could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose Opening GitHub issues ahead of time contributes to the Openness of the Apache Arrow project. Then could you also rename the pull request title in the following format? or After updating the title, you can mark the pull request as ready for review. See also: |
|
CI results for the new tests. Tests-only commit, before the fix:
With the fix commit, A few known failures seen previously also appeared. They are not related to this PR. |
|
|
Add tests for the LLVM integer constants and for IF with negative results. The constants test fails on every LLVM version tested. The IF test fails or aborts on recent LLVM and passes on LLVM 18, until the next commit.
…:int_constant LLVMTypes::int_constant built llvm::APInt(N, val) without the signed flag. For a negative value narrower than 64 bits the APInt had bits set above its width, which gives wrong results or an assertion on recent LLVM. An i128 value was not sign-extended. Co-authored-by: Logan Riggs <logan.riggs@dremio.com>
6515e84 to
fea0deb
Compare
Rationale for this change
LLVMTypes::int_constantbuildsllvm::APInt(N, val)without the signed flag. For a negative value narrower than 64 bits, theAPInthas bits set above its width, and ani128value is not sign-extended. The effect depends on the LLVM version:if (k == 0) 10 else -5returns-5for every row.Value is not an N-bit unsigned valuein theAPIntconstructor.i128constant is wrong on every version.The same fix exists in the Dremio fork (dremio/arrow 3950ea6).
What changes are included in this PR?
The fix is a one-line change in
llvm_types.h: passstd::is_signed<ctype>::valueas the signed flag ofAPIntinLLVMTypes::int_constant.The PR has two commits: the tests first, then the fix.
Are these changes tested?
Yes. Two new tests:
TestLLVMTypes.SignedIntegerConstantschecks the 8, 16, 32, 64 and 128 bit constants. Before the fix it fails on every LLVM version tested (18, 21, 23).TestIfExpr.TestNegativeConstantsevaluatesif (k == 0) 10 else -5andif (k == 0) -5 else 10forint16,int32andint64, with optimization off and on. Before the fix it returns wrong results on LLVM 21 and aborts on LLVM 23. It passes on LLVM 18, where theAPIntconstructor already clears the unused bits.Both pass with the fix. The CI run on the tests-only commit shows the results per platform.
Are there any user-facing changes?
No.
This PR contains a "Critical Fix". It fixes a bug that produced incorrect data on recent LLVM versions.
Was AI used for this PR?
AI tools helped investigate the bug and write the tests and description.
PR code and description written by:
Reviewed before submission by: