Hello!
I found a strange case related to InstCombinePass.
When I compiled this code snippet with /O2 using clang-cl.exe,
uint64_t func(uint64_t a, uint64_t b, uint64_t c) {
uint64_t L_2 = a;
uint64_t L_5 = b;
uint64_t L_8 = c;
uint64_t V_0 = 0;
// il2cpp_codegen_add(a, b) is equivalent into 'a + b'
V_0 = (
(int64_t)il2cpp_codegen_add(
((int64_t)il2cpp_codegen_add(
(int64_t)L_2, ((int64_t)((uint64_t)L_5>>((int32_t)32))))
),
((int64_t)((uint64_t)L_8>>((int32_t)32)))
)
);
uint64_t L_9 = V_0;
if (((int64_t)((int64_t)L_9&((int64_t)(std::numeric_limits<int64_t>::min)()))))
{
goto IL_0047;
}
uint64_t L_10 = V_0;
V_0 = ((int64_t)((int64_t)L_10<<1));
int32_t* L_11 = ___pexp2;
int32_t* L_12 = ___pexp2;
int32_t L_13 = *((int32_t*)L_12);
// il2cpp_codegen_subtract is equivalent to 'L_13 - 1'
*((int32_t*)L_11) = (int32_t)((int32_t)il2cpp_codegen_subtract(L_13, 1));
IL_0047:
uint64_t L_14 = V_0;
return L_14;
}
I got this IR code where the if-statement has been removed so that the executable did not work correctly. Since the predicate above can be both true and false, the if-statement shouldnât be removed.
13: ; preds = %7, %12
%14 = lshr i64 %1, 32, !dbg !36985
%15 = lshr i64 %0, 32, !dbg !36985
%16 = mul nuw nsw i64 %14, %15, !dbg !36991
%17 = and i64 %1, 4294967295, !dbg !36995
%18 = mul nuw nsw i64 %17, %15, !dbg !36998
%19 = and i64 %0, 4294967295, !dbg !37002
%20 = mul nuw nsw i64 %14, %19, !dbg !37005
%21 = lshr i64 %20, 32, !dbg !37006
%22 = lshr i64 %18, 32, !dbg !37006
%23 = add nuw nsw i64 %22, %16, !dbg !37009
%24 = add nuw nsw i64 %23, %21, !dbg !37012
%25 = shl nuw i64 %24, 1, !dbg !37014
%26 = load i32, ptr %2, align 4, !dbg !37015
%27 = add nsw i32 %26, -1, !dbg !37018
store i32 %27, ptr %2, align 4, !dbg !37019
ret i64 %25, !dbg !37020
When I disabled InstCombinePass by commenting out all âaddPass(InstCombinePass());â calls in PassBuilderPipelines.cpp, I got this code correctly woring.
13: ; preds = %7, %12
%14 = lshr i64 %1, 32, !dbg !37401
%15 = trunc i64 %14 to i32, !dbg !37401
%16 = lshr i64 %0, 32, !dbg !37401
%17 = trunc i64 %16 to i32, !dbg !37401
%18 = zext i32 %15 to i64, !dbg !37405
%19 = zext i32 %17 to i64, !dbg !37405
%20 = mul nuw nsw i64 %18, %19, !dbg !37408
%21 = trunc i64 %1 to i32, !dbg !37409
%22 = zext i32 %21 to i64, !dbg !37413
%23 = mul nuw nsw i64 %22, %19, !dbg !37416
%24 = trunc i64 %0 to i32, !dbg !37417
%25 = zext i32 %24 to i64, !dbg !37421
%26 = mul nuw nsw i64 %18, %25, !dbg !37424
%27 = lshr i64 %26, 32, !dbg !37425
%28 = lshr i64 %23, 32, !dbg !37425
%29 = add nuw nsw i64 %28, %20, !dbg !37428
%30 = add nuw nsw i64 %29, %27, !dbg !37431
%31 = and i64 %30, -9223372036854775808, !dbg !37432
%32 = icmp ne i64 %31, 0, !dbg !37432
%33 = select i1 %32, i32 2, i32 0, !dbg !37395
%34 = icmp eq i32 %33, 0
br i1 %34, label %35, label %39
35: ; preds = %13
%36 = shl i64 %30, 1, !dbg !37434
%37 = load i32, ptr %2, align 4, !dbg !37435
%38 = sub nsw i32 %37, 1, !dbg !37438
store i32 %38, ptr %2, align 4, !dbg !37439
br label %39, !dbg !37440
39: ; preds = %13, %35
%40 = phi i64 [ %30, %13 ], [ %36, %35 ]
ret i64 %40, !dbg !37441
Does anyone who understands InstCombinePass very well help me to figure why this happened and how to resolve this case?
Thank you for any help!