Open tgross35 opened 1 month ago
incorrect value with endianness flipped
Flipped endianess would be 0x1 << (128-8)
, no? This is some sort of mixed endianess where the two 64bit-chunks are little-endian but then internally they're big-endian.
Yeah, more like maintaining scalar endianness but laying out a composite struct f128 { uint8_t upper, lower; }
representation as if it is for the incorrect endianness.
@llvm/issue-subscribers-backend-powerpc
Author: Trevor Gross (tgross35)
Looking at the generated assembly (compiler explorer):
entry:
mtvsrdd 34, 4, 3
blr
main:
# <prelude omitted>
li 3, 0
li 4, 1
bl entry
nop
stxv 34, 128(1)
# <rest of function>
and a copy of the Power ISA manual, the miscompilation appears to be in the entry function. The 128-bit integer is passed in GPR 3 and 4. The entry
function then combines the GPR registers the wrong way round with mtvsrdd 34, 4, 3
, placing the second doubleword at the start of the vector register instead of at the end.
Hi!
This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:
test/
create fine-grained testing targets, so you can e.g. use make check-clang-ast
to only run Clang's AST tests.git clang-format HEAD~1
to format your changes.If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.
@llvm/issue-subscribers-good-first-issue
Author: Trevor Gross (tgross35)
Doing a roundtrip i128 -> f128 -> i128 should work but it appears to be broken when the calls are external, possibly depending on some optimizations. It seems like the
f128
/i128
is getting split into two 64-bit values, which are getting reversed at some point. The problem does not seem to happen without enabling the pwr9 target feature.Originally identified with rust in https://github.com/rust-lang/rust/issues/125102. Source files:
Versions:
Compilation:
Execution:
The above should output 0. Full IR:
Library function
```llvm ; ModuleID = 'transmute_lib.1e179323af95c5c5-cgu.0' source_filename = "transmute_lib.1e179323af95c5c5-cgu.0" target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" target triple = "powerpc64-unknown-linux-gnu" ; Function Attrs: uwtable define fp128 @entry(i128 %a) unnamed_addr #0 { start: %_0 = bitcast i128 %a to fp128 ret fp128 %_0 } attributes #0 = { uwtable "probe-stack"="inline-asm" "target-cpu"="pwr9" } !llvm.module.flags = !{!0} !llvm.ident = !{!1} !0 = !{i32 8, !"PIC Level", i32 2} !1 = !{!"rustc version 1.80.0-nightly (9c9b56879 2024-05-05)"} ```Executable
The only relevant part is in `transmute_call_lib::main` ```llvm ; ModuleID = 'transmute_call_lib.1791869a4d73965-cgu.0' source_filename = "transmute_call_lib.1791869a4d73965-cgu.0" target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" target triple = "powerpc64-unknown-linux-gnu" @vtable.0 = private unnamed_addr constant <{ ptr, [16 x i8], ptr, ptr, ptr }> <{ ptr @"_ZN4core3ptr85drop_in_place$LT$std..rt..lan ; std::sys_common::backtrace::__rust_begin_short_backtrace ; Function Attrs: noinline uwtable define internal void @_ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17hf94855fdbb5829c5E(ptr %f) unnamed_addr #0 { start: ; call core::ops::function::FnOnce::call_once call void @_ZN4core3ops8function6FnOnce9call_once17h3056e9bd87d66482E(ptr %f) call void asm sideeffect "", "~{memory}"(), !srcloc !3 ret void } ; std::rt::lang_start ; Function Attrs: uwtable define hidden i64 @_ZN3std2rt10lang_start17hdc6989dbc5702db1E(ptr %main, i64 %argc, ptr %argv, i8 %sigpipe) unnamed_addr #1 { start: %_8 = alloca [8 x i8], align 8 %_5 = alloca [8 x i8], align 8 store ptr %main, ptr %_8, align 8 ; call std::rt::lang_start_internal %0 = call i64 @_ZN3std2rt19lang_start_internal17he440c14c55fd4760E(ptr align 1 %_8, ptr align 8 @vtable.0, i64 %argc, ptr %argv, store i64 %0, ptr %_5, align 8 %v = load i64, ptr %_5, align 8 ret i64 %v } ; std::rt::lang_start::{{closure}} ; Function Attrs: inlinehint uwtable define internal i32 @"_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17hdb386b686ec8565dE"(ptr align 8 %_1) unnamed_addr #2 { start: %self = alloca [1 x i8], align 1 %_4 = load ptr, ptr %_1, align 8 ; call std::sys_common::backtrace::__rust_begin_short_backtrace call void @_ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17hf94855fdbb5829c5E(ptr %_4) ; call <() as std::process::Termination>::report %0 = call i8 @"_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h3606faab680ab85fE"() store i8 %0, ptr %self, align 1 %_6 = load i8, ptr %self, align 1 %_0 = zext i8 %_6 to i32 ret i32 %_0 } ; core::ops::function::FnOnce::call_once{{vtable.shim}} ; Function Attrs: inlinehint uwtable define internal i32 @"_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h956497c27ef6ef7fE"(ptr %_1) unnamed start: %_2 = alloca [0 x i8], align 1 %0 = load ptr, ptr %_1, align 8 ; call core::ops::function::FnOnce::call_once %_0 = call i32 @_ZN4core3ops8function6FnOnce9call_once17h9737a54d47c05e22E(ptr %0) ret i32 %_0 } ; core::ops::function::FnOnce::call_once ; Function Attrs: inlinehint uwtable define internal void @_ZN4core3ops8function6FnOnce9call_once17h3056e9bd87d66482E(ptr %_1) unnamed_addr #2 { start: %_2 = alloca [0 x i8], align 1 call void %_1() ret void } ; core::ops::function::FnOnce::call_once ; Function Attrs: inlinehint uwtable define internal i32 @_ZN4core3ops8function6FnOnce9call_once17h9737a54d47c05e22E(ptr %0) unnamed_addr #2 personality ptr @rust_eh_p start: %1 = alloca [16 x i8], align 8 %_2 = alloca [0 x i8], align 1 %_1 = alloca [8 x i8], align 8 store ptr %0, ptr %_1, align 8 ; invoke std::rt::lang_start::{{closure}} %_0 = invoke i32 @"_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17hdb386b686ec8565dE"(ptr align 8 %_1) to label %bb1 unwind label %cleanup bb3: ; preds = %cleanup %2 = load ptr, ptr %1, align 8 %3 = getelementptr inbounds i8, ptr %1, i64 8 %4 = load i32, ptr %3, align 8 %5 = insertvalue { ptr, i32 } poison, ptr %2, 0 %6 = insertvalue { ptr, i32 } %5, i32 %4, 1 resume { ptr, i32 } %6 cleanup: ; preds = %start %7 = landingpad { ptr, i32 } cleanup %8 = extractvalue { ptr, i32 } %7, 0 %9 = extractvalue { ptr, i32 } %7, 1 store ptr %8, ptr %1, align 8 %10 = getelementptr inbounds i8, ptr %1, i64 8 store i32 %9, ptr %10, align 8 br label %bb3 bb1: ; preds = %start ret i32 %_0 } ; core::ptr::drop_in_placeThis could be indirectly related to https://github.com/llvm/llvm-project/issues/92233#issuecomment-2112775463 since that needs use of
f128
to cause the crash.