This is an archive of the discontinued LLVM Phabricator instance.

[ExecutionEngine] Fix R_AARCH64_ABS{16,32} assertion
AbandonedPublic

Authored by treapster on Mar 22 2023, 3:10 AM.

Details

Reviewers
hiraditya
MaskRay
Summary

Previous version of assertion effectively prevented negative Result values because it didn't cast to int64_t. Fix it by adding the cast.

Diff Detail

Event Timeline

treapster created this revision.Mar 22 2023, 3:10 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 22 2023, 3:10 AM
treapster requested review of this revision.Mar 22 2023, 3:10 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 22 2023, 3:10 AM

This commit has the same tests failing so it's not me:)

MaskRay requested changes to this revision.Apr 5 2023, 6:54 AM
MaskRay added inline comments.
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
429

The change is incorrect.

R_AARCH64_ABS16 permits either signed or unsigned narrow values. See https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst

The original assert conditions had off-by-1 issues, which I just fixed in 7b58259481417bb22d144a9c12ee8f4fb0a046e0.

This revision now requires changes to proceed.Apr 5 2023, 6:54 AM
MaskRay added inline comments.Apr 5 2023, 6:56 AM
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
429

Sorry, I'll fix my conditions according to lld/ELF/Target.h in a few hours...

treapster added inline comments.Apr 5 2023, 8:48 AM
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
429

Why is it incorrect? It follows the same logic as assertions in other cases, we cast to signed because otherwise negative value results in second expression being false. Your off-by-one fix still does not allow negative values.

@MaskRay

#include <iostream>
#include <cstdint>
#define INT32_MIN		(-2147483647-1)
#define UINT32_MAX		(4294967295U)

int main() {
    uint64_t Result = -4ull;
    std::cout << "Original: " <<
        (static_cast<int64_t>(Result) >= INT32_MIN && Result < UINT32_MAX) << "\n";

    std::cout << "Less or equal: " <<
        (static_cast<int64_t>(Result) >= INT32_MIN && Result <= UINT32_MAX) << "\n";

    std::cout << "With cast: " <<
        (static_cast<int64_t>(Result) >= INT32_MIN &&
        static_cast<int64_t>(Result) <= UINT32_MAX) << "\n";

}

Results in

Original: 0
Less or equal: 0
With cast: 1

We need both <= and cast.

We need both <= and cast.

But your SignExtend patch is doing the same thing, thanks.