You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I came across strange behavior. With enabled optimization when inlined function is provided with the address of external symbol (as argument) the two least bits of the constant used inside that function get cleared. Looks like optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constatnt value used for bitwise AND operation with that address.
This is target independent behavior (checked this for X86, ARM and RISCV targets) because constant has aligned value already in IR.
Narrowed it down to simple program. IR can be generated with clang --target=arm-none-eabi test.c -Og -S -emit-llvm
After debugging it a bit I found that consntant changes its value when test function gets actually inlined at some step in InstCombinePass or InlinerPass optimization pass. Problem exists at any level of optimization except -O0 (bcs in this case function is not inlined).
Bad case C code
#defineSOC_MMU_LINEAR_ADDR_MASK 0x1FFFFFF
externint_instruction_reserved_end;
__attribute__((always_inline))
staticinlineunsigned inttest(unsigned intvaddr)
{
returnvaddr&SOC_MMU_LINEAR_ADDR_MASK;
}
intmain()
{
// this produces inlined IR with wrongly aligned constant value 0x1FFFFFCvolatileunsigned inttmp=test((unsigned int)&_instruction_reserved_end);
returntmp;
}
IR for bad case. Note %2 = and i32 ptrtoint (ptr @_instruction_reserved_end to i32), 33554428
Ok. Looks like the behavior can be considered as normal because external symbol is declared as int. For char problem does not appear.
In my case extern int _instruction_reserved_end; is the declaration of linker symbol which can be unaligned to 4-bytes. Changing it to char solves the problem. So issue can be closed if this behavior is expected.
Hi guys!
I came across strange behavior. With enabled optimization when inlined function is provided with the address of external symbol (as argument) the two least bits of the constant used inside that function get cleared. Looks like optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constatnt value used for bitwise
AND
operation with that address.This is target independent behavior (checked this for X86, ARM and RISCV targets) because constant has aligned value already in IR.
Narrowed it down to simple program. IR can be generated with
clang --target=arm-none-eabi test.c -Og -S -emit-llvm
After debugging it a bit I found that consntant changes its value when
test
function gets actually inlined at some step inInstCombinePass
orInlinerPass
optimization pass. Problem exists at any level of optimization except-O0
(bcs in this case function is not inlined).Bad case C code
IR for bad case. Note
%2 = and i32 ptrtoint (ptr @_instruction_reserved_end to i32), 33554428
Good case C code
IR for good case. Note
%4 = and i32 %3, 33554431
The text was updated successfully, but these errors were encountered: