www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - Infinite recursion with memcpy and memset/memclr lowerings

reply Mike Franklin <slavo5150 yahoo.com> writes:
I ran into an interesting situation with my ARM Cortex-M 
experiment using LDC.

I have this function:

extern(C) void* __aeabi_memclr(void* dest, size_t num)
{
     byte* d = cast(byte*)dest;
     for(int i = 0; i < num; i++)
     {
         d[i] = cast(byte)0;
     }

     return dest;
}

LDC seems to recognize the body of the function and rewrites it 
as `__aeabi_memclr`, causing infinite recursion.  Is there some 
way I can instruct the compiler to stop doing that?

Mike
Jul 19 2018
next sibling parent reply kinke <kinke libero.it> writes:
On Thursday, 19 July 2018 at 12:12:28 UTC, Mike Franklin wrote:
 I ran into an interesting situation with my ARM Cortex-M 
 experiment using LDC.

 I have this function:

 extern(C) void* __aeabi_memclr(void* dest, size_t num)
 {
     byte* d = cast(byte*)dest;
     for(int i = 0; i < num; i++)
     {
         d[i] = cast(byte)0;
     }

     return dest;
 }

 LDC seems to recognize the body of the function and rewrites it 
 as `__aeabi_memclr`, causing infinite recursion.  Is there some 
 way I can instruct the compiler to stop doing that?

 Mike
Related: https://users.rust-lang.org/t/--aeabi-memclr-compiling-to-suicide-loop/4451 I don't know how to prevent LLVM from assuming the compiler-rt builtins are available. If you don't insist on implementing everything yourself, you could use LLVM's implementations in compiler-rt, e.g., by a simple forward declaration or by using the LLVM memset intrinsic (see ldc.intrinsics) and obviously linking against the compiler-rt builtins lib (e.g., https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/arm/aeabi_memset.S).
Jul 19 2018
parent reply Mike Franklin <slavo5150 yahoo.com> writes:
On Thursday, 19 July 2018 at 14:51:02 UTC, kinke wrote:
 Related: 
 https://users.rust-lang.org/t/--aeabi-memclr-compiling-to-suicide-loop/4451

 I don't know how to prevent LLVM from assuming the compiler-rt 
 builtins are available.

 If you don't insist on implementing everything yourself, you 
 could use LLVM's implementations in compiler-rt, e.g., by a 
 simple forward declaration or by using the LLVM memset 
 intrinsic (see ldc.intrinsics) and obviously linking against 
 the compiler-rt builtins lib (e.g., 
 https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/arm/aeabi_memset.S).
Correct me if I'm wrong, but it appears that forwarding to compiler-rt's implementation or using `ldc.intrinsics` will require linking in a C standard library. I'd prefer to avoid that. Mike
Jul 19 2018
parent reply Mike Franklin <slavo5150 yahoo.com> writes:
On Thursday, 19 July 2018 at 22:36:37 UTC, Mike Franklin wrote:

 Correct me if I'm wrong, but it appears that forwarding to 
 compiler-rt's implementation or using `ldc.intrinsics` will 
 require linking in a C standard library.  I'd prefer to avoid 
 that.
FYI, I tried to implement my own `memcpy` and `memset` implementations and just have `__aeabi_memcpy` and `__aeabi_memclr` forward to those, but then the compiler recognized the `memcpy` and `memset` calls and replaced them with `__aeabi_memcpy` and `__aeabi_memclr`. :-/ Mike
Jul 19 2018
parent "David Nadlinger" <code klickverbot.at> writes:
On 20 Jul 2018, at 2:35, Mike Franklin via digitalmars-d-ldc wrote:
 FYI, I tried to implement my own `memcpy` and `memset` implementations 
 and just have `__aeabi_memcpy` and `__aeabi_memclr` forward to those, 
 but then the compiler recognized the `memcpy` and `memset` calls and 
 replaced them with `__aeabi_memcpy` and `__aeabi_memclr`.  :-/
Yep, this is expected behaviour without something like `-fno-builtin` or `-disable-simplify-libcalls`. C runtime libraries (glibc/compiler-rt…) are of course in exactly the same situation with GCC/Clang. — David
Jul 21 2018
prev sibling parent reply Johan Engelen <j j.nl> writes:
On Thursday, 19 July 2018 at 12:12:28 UTC, Mike Franklin wrote:
 LDC seems to recognize the body of the function and rewrites it 
 as `__aeabi_memclr`, causing infinite recursion.  Is there some 
 way I can instruct the compiler to stop doing that?
You can use `-disable-simplify-libcalls`. Looks like we need to implement something equivalent to Clang's `-fno-builtin` or `-ffreestanding` etc. After some quick research, I don't think it is currently possible to disable these optimizations just for one function, can only disable it for one compiler invoke. -Johan
Jul 19 2018
next sibling parent Mike Franklin <slavo5150 yahoo.com> writes:
On Thursday, 19 July 2018 at 18:49:07 UTC, Johan Engelen wrote:

 You can use `-disable-simplify-libcalls`.
Thanks! That fixes things for now. Mike
Jul 19 2018
prev sibling parent Johan Engelen <j j.nl> writes:
On Thursday, 19 July 2018 at 18:49:07 UTC, Johan Engelen wrote:
 On Thursday, 19 July 2018 at 12:12:28 UTC, Mike Franklin wrote:
 LDC seems to recognize the body of the function and rewrites 
 it as `__aeabi_memclr`, causing infinite recursion.  Is there 
 some way I can instruct the compiler to stop doing that?
You can use `-disable-simplify-libcalls`. Looks like we need to implement something equivalent to Clang's `-fno-builtin` or `-ffreestanding` etc. After some quick research, I don't think it is currently possible to disable these optimizations just for one function, can only disable it for one compiler invoke.
LLVM now supports disabling these optimizations per function: https://reviews.llvm.org/rG878ab6df033 https://github.com/ldc-developers/ldc/issues/3263
Dec 24 2019