-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Closed
Description
For
[MethodImpl(MethodImplOptions.NoInlining)]
public static byte GetElement(byte* array)
{
return array[0];
}We generate the following LLVM IR (-O0):
; Function Attrs: noinline uwtable
define monocc i8 @"Program:GetElement (byte*)"(i64* %arg_array) #0 {
BB0:
br label %BB3
BB3: ; preds = %BB0
br label %BB2
BB2: ; preds = %BB3
%0 = bitcast i64* %arg_array to i8*
%1 = load i8, i8* %0
%2 = zext i8 %1 to i32
%3 = trunc i32 %2 to i8
%t18 = zext i8 %3 to i32
br label %BB4
BB4: ; preds = %BB2
br label %BB1
BB1: ; preds = %BB4
%4 = trunc i32 %t18 to i8
ret i8 %4
}As you can see the argument is i64* (long*) which then is bitcasted to i8* So why don't we use real pointers here? For this case it's fine - LLVM is able to optimize it to a single mov but in more complicated scenarios it seems it's a problem:
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ZeroArray(byte* array, int len)
{
for (int i=0; i<len; i++)
{
array[i] = 0;
}
}Ideally this code should be optimized to a single memset call, e.g. C++ does it:
- C++ to LLVM IR: https://godbolt.org/z/JP7j7l
opt -O1for that LLVM IR: https://godbolt.org/z/VEHQVp recognizes memset (as you can seeInduction Variable Simplificationpass did the magic trick)- LLVM IR to asm (llc) https://godbolt.org/z/4B_3HK
But the LLVM IR that mono generates can not be optimized due to redundant bitcast/inttoptr/ptrtoint operations: https://godbolt.org/z/rC0v3Z