Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #325 #326

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Fix issue #325 #326

wants to merge 5 commits into from

Conversation

frabert
Copy link
Collaborator

@frabert frabert commented May 19, 2023

No description provided.

@github-actions
Copy link

See the diff generated by this PR for the tests here: https://github.com/lifting-bits/rellic/actions/runs/5022831295

fizzbuzz.bc

--- /dev/fd/63	2023-05-19 09:28:43.731950806 +0000
+++ /dev/fd/62	2023-05-19 09:28:43.731950806 +0000
@@ -7,14 +7,30 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
     var0 = 0U;
     var1 = 0U;
-    while ((int)var1 < 30)
-        {
-            if ((int)var1 % 5 != 0U || (int)var1 % 3 != 0U) {
-                if ((int)var1 % 3 != 0U) {
-                    if ((int)var1 % 5 != 0U) {
-                        printf("%d\n", var1);
+    do {
+        val2 = var1;
+        if ((int)val2 < 30) {
+            val3 = var1;
+            if ((int)val3 % 3 == 0U) {
+                val4 = var1;
+            }
+            if ((int)val4 % 5 != 0U || (int)val3 % 3 != 0U) {
+                val5 = var1;
+                if ((int)val5 % 3 != 0U) {
+                    val6 = var1;
+                    if ((int)val6 % 5 != 0U) {
+                        val7 = var1;
+                        printf("%d\n", val7);
                     } else {
                         printf("buzz\n");
                     }
@@ -24,7 +40,10 @@
             } else {
                 printf("fizzbuzz\n");
             }
-            var1 = var1 + 1U;
+            val8 = var1;
+            var1 = val8 + 1U;
         }
-    return var0;
+    } while ((int)val2 < 30);
+    val9 = var0;
+    return val9;
 }

typedefs_of_typedefs.bc

--- /dev/fd/63	2023-05-19 09:28:44.615970076 +0000
+++ /dev/fd/62	2023-05-19 09:28:44.615970076 +0000
@@ -12,16 +12,44 @@
     __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long var5;
     __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long var6;
     void *var7;
+    __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long val8;
+    __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long val9;
+    __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long val10;
+    __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long val11;
+    __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long val12;
+    __attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long val13;
+    void *val14;
+    unsigned int val15;
+    void *val16;
+    unsigned int val17;
+    unsigned long val18;
+    unsigned long val19;
+    unsigned long val20;
+    unsigned long val21;
     var0 = 0U;
     var4 = (__attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long){1UL, 2UL};
-    var1 = var4;
+    val8 = var4;
+    var1 = val8;
     var5 = (__attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long){};
-    var2 = var5;
+    val9 = var5;
+    var2 = val9;
     var6 = (__attribute__((__vector_size__(2 * sizeof(unsigned long)))) unsigned long){4UL, 3UL};
-    var3 = var6;
-    var1 = var1 * var2 + var3;
+    val10 = var6;
+    var3 = val10;
+    val11 = var1;
+    val12 = var2;
+    val13 = var3;
+    var1 = val11 * val12 + val13;
     var7 = &var1;
-    printf("a=[%d %d]\n", *((unsigned int *)var7), ((unsigned int *)var7)[1UL]);
-    printf("array=[%lld %lld %lld %lld]\n", *(unsigned long *)(&array), array[1UL], array[2UL], array[3UL]);
+    val14 = var7;
+    val15 = *((unsigned int *)val14);
+    val16 = var7;
+    val17 = ((unsigned int *)val16)[1UL];
+    printf("a=[%d %d]\n", val15, val17);
+    val18 = *(unsigned long *)(&array);
+    val19 = array[1UL];
+    val20 = array[2UL];
+    val21 = array[3UL];
+    printf("array=[%lld %lld %lld %lld]\n", val18, val19, val20, val21);
     return 0U;
 }

switch_loop.bc

--- /dev/fd/63	2023-05-19 09:28:44.683971558 +0000
+++ /dev/fd/62	2023-05-19 09:28:44.683971558 +0000
@@ -4,19 +4,31 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
     var0 = 0U;
     var1 = 0U;
     do {
-        var1 = var1 + 1U;
-        if (!(var1 != 2U && var1 != 3U && var1 != 1U))
-            if (var1 == 3U) {
-                printf("%d\n", var1);
+        val2 = var1;
+        var1 = val2 + 1U;
+        val3 = var1;
+        if (!(val3 != 2U && val3 != 3U && val3 != 1U))
+            if (val3 == 3U) {
+                val6 = var1;
+                printf("%d\n", val6);
                 break;
-            } else if (var1 == 2U) {
-                printf("%d\n", var1);
+            } else if (val3 == 2U) {
+                val5 = var1;
+                printf("%d\n", val5);
             } else {
-                printf("%d\n", var1);
+                val4 = var1;
+                printf("%d\n", val4);
             }
-    } while (!(var1 != 2U && var1 != 3U && var1 != 1U));
-    return var0;
+    } while (!(val3 != 2U && val3 != 3U && val3 != 1U));
+    val7 = var0;
+    return val7;
 }

func_cond_zero_arg.bc

--- /dev/fd/63	2023-05-19 09:28:44.935977051 +0000
+++ /dev/fd/62	2023-05-19 09:28:44.935977051 +0000
@@ -8,6 +8,7 @@
 int main(void) {
     unsigned int var0;
     unsigned int call1;
+    unsigned int val2;
     var0 = 0U;
     call1 = f();
     if (call1 == 0U) {
@@ -15,5 +16,6 @@
     } else {
         var0 = 1U;
     }
-    return var0;
+    val2 = var0;
+    return val2;
 }

fcmp.bc

--- /dev/fd/63	2023-05-19 09:28:45.063979842 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.063979842 +0000
@@ -17,18 +17,56 @@
     unsigned int var9;
     float call10;
     float call11;
+    float val12;
+    float val13;
+    float val14;
+    float val15;
+    float val16;
+    float val17;
+    float val18;
+    float val19;
+    float val20;
+    float val21;
+    float val22;
+    float val23;
+    float val24;
+    unsigned int val25;
+    unsigned int val26;
+    unsigned int val27;
+    unsigned int val28;
+    unsigned int val29;
+    unsigned int val30;
     var0 = __builtin_nan("");
     call10 = atof("3");
     var1 = call10;
     call11 = atof("2");
     var2 = call11;
-    var3 = -var1;
-    var4 = (var3 > var0);
-    var5 = (var3 >= var0);
-    var6 = (var1 > var2);
-    var7 = (var1 >= var2);
-    var8 = __builtin_isunordered(var1, var0);
-    var9 = __builtin_isunordered(var1, var2);
-    printf("%d %d %d %d %d %d\n", var4, var5, var6, var7, var8, var9);
+    val12 = var1;
+    var3 = -val12;
+    val13 = var3;
+    val14 = var0;
+    var4 = (val13 > val14);
+    val15 = var3;
+    val16 = var0;
+    var5 = (val15 >= val16);
+    val17 = var1;
+    val18 = var2;
+    var6 = (val17 > val18);
+    val19 = var1;
+    val20 = var2;
+    var7 = (val19 >= val20);
+    val21 = var1;
+    val22 = var0;
+    var8 = __builtin_isunordered(val21, val22);
+    val23 = var1;
+    val24 = var2;
+    var9 = __builtin_isunordered(val23, val24);
+    val25 = var4;
+    val26 = var5;
+    val27 = var6;
+    val28 = var7;
+    val29 = var8;
+    val30 = var9;
+    printf("%d %d %d %d %d %d\n", val25, val26, val27, val28, val29, val30);
     return 0U;
 }

conflicting_names.bc

--- /dev/fd/63	2023-05-19 09:28:45.131981324 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.131981324 +0000
@@ -4,13 +4,17 @@
 unsigned int atoi(void *arg0);
 unsigned int foo(void) {
     unsigned int var0;
+    unsigned int val1;
     var0 = 0U;
-    return var0;
+    val1 = var0;
+    return val1;
 }
 unsigned int bar(void) {
     unsigned int var0;
+    unsigned int val1;
     var0 = 1U;
-    return var0;
+    val1 = var0;
+    return val1;
 }
 int main(void) {
     unsigned int var0;
@@ -20,21 +24,35 @@
     unsigned int var4;
     unsigned int var5;
     unsigned int var6;
-    unsigned int call7;
+    unsigned int val7;
+    void *val8;
+    void *val9;
+    unsigned int call10;
+    unsigned int val11;
+    unsigned int val12;
+    unsigned int val13;
+    unsigned int val14;
     var0 = 0U;
     var1 = 0U;
     var2 = (void *)0U;
     var3 = 0U;
-    if (1 >= (int)var1) {
+    val7 = var1;
+    if (1 >= (int)val7) {
         var6 = 1U;
-        var3 = var6;
+        val13 = var6;
+        var3 = val13;
     } else {
-        call7 = atoi(((void **)var2)[1UL]);
-        var4 = call7;
-        if ((int)var4 > 10) {
+        val8 = var2;
+        val9 = ((void **)val8)[1UL];
+        call10 = atoi(val9);
+        var4 = call10;
+        val11 = var4;
+        if ((int)val11 > 10) {
             var5 = 99U;
-            var3 = var5;
+            val12 = var5;
+            var3 = val12;
         }
     }
-    return var3;
+    val14 = var3;
+    return val14;
 }

struct.bc

--- /dev/fd/63	2023-05-19 09:28:45.319985422 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.319985422 +0000
@@ -6,11 +6,19 @@
 struct struct__pair a = {0U, 42U};
 int main(void) {
     unsigned int var0;
+    unsigned int val1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
     var0 = 0U;
-    if (*(unsigned int *)(&a) == 0U) {
-        var0 = a.field1;
+    val1 = *(unsigned int *)(&a);
+    if (val1 == 0U) {
+        val3 = a.field1;
+        var0 = val3;
     } else {
-        var0 = *(unsigned int *)(&a);
+        val2 = *(unsigned int *)(&a);
+        var0 = val2;
     }
-    return var0;
+    val4 = var0;
+    return val4;
 }

issue_183_literal_structs.bc

--- /dev/fd/63	2023-05-19 09:28:45.447988212 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.447988212 +0000
@@ -20,15 +20,21 @@
 };
 unsigned int bar(unsigned long arg0, unsigned long arg1) {
     struct struct_foo_t var0;
+    unsigned int val1;
     ((struct literal_struct_0 *)(&var0))->field0 = arg0;
     ((struct literal_struct_0 *)(&var0))->field1 = arg1;
-    return *(unsigned int *)(&var0.field3);
+    val1 = *(unsigned int *)(&var0.field3);
+    return val1;
 }
 int main(void) {
     struct struct_foo_t var0;
-    unsigned int call1;
+    unsigned long val1;
+    unsigned long val2;
+    unsigned int call3;
     *(unsigned int *)(&var0.field3) = 3U;
-    call1 = bar(((struct literal_struct_0 *)(&var0))->field0, ((struct literal_struct_0 *)(&var0))->field1);
-    printf("%d\n", call1);
+    val1 = ((struct literal_struct_0 *)(&var0))->field0;
+    val2 = ((struct literal_struct_0 *)(&var0))->field1;
+    call3 = bar(val1, val2);
+    printf("%d\n", call3);
     return 0U;
 }

zeroinit.bc

--- /dev/fd/63	2023-05-19 09:28:45.519989782 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.519989782 +0000
@@ -16,9 +16,14 @@
 unsigned long a1[256] = {};
 int main(void) {
     unsigned int var0;
+    unsigned int val1;
+    unsigned long val2;
+    unsigned int val3;
     var0 = 0U;
-    if (*(unsigned int *)(&r1.field1) == 0U) {
-        if (a1[42UL] == 0UL) {
+    val1 = *(unsigned int *)(&r1.field1);
+    if (val1 == 0U) {
+        val2 = a1[42UL];
+        if (val2 == 0UL) {
             var0 = 0U;
         } else {
             var0 = 2U;
@@ -26,5 +31,6 @@
     } else {
         var0 = 1U;
     }
-    return var0;
+    val3 = var0;
+    return val3;
 }

issue_127_uint128_t_lit.bc

--- /dev/fd/63	2023-05-19 09:28:45.715994055 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.715994055 +0000
@@ -2,8 +2,10 @@
 unsigned __int128 x = (unsigned __int128)3735928559ULL;
 int main(void) {
     unsigned int var0;
-    unsigned char val1;
+    unsigned __int128 val1;
+    unsigned char val2;
     var0 = 0U;
-    val1 = (x & (unsigned __int128)65535ULL) == (unsigned __int128)48879ULL;
-    return val1 ? 0U : 1U;
+    val1 = x;
+    val2 = (val1 & (unsigned __int128)65535ULL) == (unsigned __int128)48879ULL;
+    return val2 ? 0U : 1U;
 }

global_using_function_decl.bc

--- /dev/fd/63	2023-05-19 09:28:45.779995450 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.779995450 +0000
@@ -7,6 +7,8 @@
     return;
 }
 int main(void) {
-    ((void (*)(unsigned int))afunc_pointer)(0U);
+    void *val0;
+    val0 = afunc_pointer;
+    ((void (*)(unsigned int))val0)(0U);
     return 0U;
 }

init_list.bc

--- /dev/fd/63	2023-05-19 09:28:45.851997019 +0000
+++ /dev/fd/62	2023-05-19 09:28:45.851997019 +0000
@@ -2,6 +2,8 @@
 unsigned int a[5] = {0U, 1U, 2U, 3U, 4U};
 int main(void) {
     unsigned int var0;
+    unsigned int val1;
     var0 = 0U;
-    return a[1UL];
+    val1 = a[1UL];
+    return val1;
 }

reg_test_structure_fields.bc

ret0.bc

goto_loop.bc

--- /dev/fd/63	2023-05-19 09:28:46.056001466 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.056001466 +0000
@@ -4,23 +4,42 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
     var0 = 0U;
     var1 = 0U;
     while (1U)
         {
-            var1 = var1 + 1U;
-            if (var1 == 1U) {
-                printf("%d\n", var1);
-            } else if (var1 != 2U) {
-                break;
+            val2 = var1;
+            var1 = val2 + 1U;
+            val3 = var1;
+            if (val3 == 1U) {
+                val4 = var1;
+                printf("%d\n", val4);
             } else {
-                printf("%d\n", var1);
+                val5 = var1;
+            }
+            if (val3 != 1U && val5 != 2U) {
+                break;
+            }
+            if (val3 != 1U && val5 == 2U) {
+                val6 = var1;
+                printf("%d\n", val6);
             }
         }
-    if (var1 != 1U && var1 != 2U) {
-        if (var1 == 3U) {
-            printf("%d\n", var1);
+    if (val3 != 1U && val5 != 2U) {
+        val7 = var1;
+        if (val7 == 3U) {
+            val8 = var1;
+            printf("%d\n", val8);
         }
-        return var0;
+        val9 = var0;
+        return val9;
     }
 }

trunc.bc

--- /dev/fd/63	2023-05-19 09:28:46.360008093 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.360008093 +0000
@@ -2,6 +2,8 @@
 unsigned long a = 18446744073709551615UL;
 int main(void) {
     unsigned int var0;
+    unsigned long val1;
     var0 = 0U;
-    return (unsigned int)a;
+    val1 = a;
+    return (unsigned int)val1;
 }

bitops.bc

--- /dev/fd/63	2023-05-19 09:28:46.428009575 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.428009575 +0000
@@ -4,14 +4,34 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
+    unsigned int val10;
+    unsigned int val11;
     var0 = 0U;
     var1 = 0U;
-    if (((int)a >> b & 1U) != 0U) {
-        var1 = var1 + 1U;
+    val2 = a;
+    val3 = b;
+    if (((int)val2 >> val3 & 1U) != 0U) {
+        val4 = var1;
+        var1 = val4 + 1U;
     }
-    if ((a >> b ^ 1U) != 0U) {
-        var1 = var1 + 2U;
+    val5 = a;
+    val6 = b;
+    if ((val5 >> val6 ^ 1U) != 0U) {
+        val7 = var1;
+        var1 = val7 + 2U;
     }
-    var1 = var1 + 3U;
-    return var1;
+    val8 = a;
+    val9 = b;
+    val10 = var1;
+    var1 = val10 + 3U;
+    val11 = var1;
+    return val11;
 }

cast.bc

nullptr.bc

--- /dev/fd/63	2023-05-19 09:28:46.700015478 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.700015478 +0000
@@ -2,11 +2,15 @@
 void *ptr = (void *)0U;
 int main(void) {
     unsigned int var0;
+    void *val1;
+    unsigned int val2;
     var0 = 0U;
-    if (ptr != (void *)0U) {
+    val1 = ptr;
+    if (val1 != (void *)0U) {
         var0 = 1U;
     } else {
         var0 = 0U;
     }
-    return var0;
+    val2 = var0;
+    return val2;
 }

nested_struct.bc

--- /dev/fd/63	2023-05-19 09:28:46.824018162 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.828018249 +0000
@@ -18,7 +18,11 @@
 char _str_1[9] = "Name: %s\000";
 int main(void) {
     unsigned int var0;
+    void *val1;
+    unsigned int val2;
     var0 = 0U;
-    printf("Name: %s", *(void **)(&r1.field2));
-    return r1.field1.field1;
+    val1 = *(void **)(&r1.field2);
+    printf("Name: %s", val1);
+    val2 = r1.field1.field1;
+    return val2;
 }

array_swap.bc

--- /dev/fd/63	2023-05-19 09:28:46.896019721 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.896019721 +0000
@@ -3,9 +3,17 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
     var0 = 0U;
-    var1 = *(unsigned int *)(&a);
-    *(unsigned int *)(&a) = a[1UL];
-    a[1UL] = var1;
-    return *(unsigned int *)(&a);
+    val2 = *(unsigned int *)(&a);
+    var1 = val2;
+    val3 = a[1UL];
+    *(unsigned int *)(&a) = val3;
+    val4 = var1;
+    a[1UL] = val4;
+    val5 = *(unsigned int *)(&a);
+    return val5;
 }

binops.bc

--- /dev/fd/63	2023-05-19 09:28:46.964021194 +0000
+++ /dev/fd/62	2023-05-19 09:28:46.964021194 +0000
@@ -4,23 +4,49 @@
     unsigned int var0;
     unsigned int var1;
     unsigned int var2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
+    unsigned int val10;
+    unsigned int val11;
+    unsigned int val12;
+    unsigned int val13;
+    unsigned int val14;
+    unsigned int val15;
     var0 = arg0;
-    var1 = var0 % 4U;
+    val3 = var0;
+    var1 = val3 % 4U;
     var2 = 0U;
-    if (var1 != 0U) {
-        if (var1 != 1U) {
-            if (var1 != 2U) {
-                var2 = (var0 + 3131756735U) * (5U & var0);
+    val4 = var1;
+    if (val4 != 0U) {
+        val7 = var1;
+        if (val7 != 1U) {
+            val10 = var1;
+            if (val10 != 2U) {
+                val13 = var0;
+                val14 = var0;
+                var2 = (val13 + 3131756735U) * (5U & val14);
             } else {
-                var2 = (var0 ^ 3131756735U) * (4U | var0);
+                val11 = var0;
+                val12 = var0;
+                var2 = (val11 ^ 3131756735U) * (4U | val12);
             }
         } else {
-            var2 = (var0 & 3131756735U) * (3U + var0);
+            val8 = var0;
+            val9 = var0;
+            var2 = (val8 & 3131756735U) * (3U + val9);
         }
     } else {
-        var2 = (var0 | 3131756735U) * (2U ^ var0);
+        val5 = var0;
+        val6 = var0;
+        var2 = (val5 | 3131756735U) * (2U ^ val6);
     }
-    return var2;
+    val15 = var2;
+    return val15;
 }
 int main(void) {
     unsigned int var0;

bitmask.bc

--- /dev/fd/63	2023-05-19 09:28:47.356029682 +0000
+++ /dev/fd/62	2023-05-19 09:28:47.356029682 +0000
@@ -2,11 +2,15 @@
 unsigned long a = 43981UL;
 int main(void) {
     unsigned int var0;
+    unsigned long val1;
+    unsigned int val2;
     var0 = 0U;
-    if ((a & 4080UL) >> 4UL != 188UL) {
+    val1 = a;
+    if ((val1 & 4080UL) >> 4UL != 188UL) {
         var0 = 1U;
     } else {
         var0 = 0U;
     }
-    return var0;
+    val2 = var0;
+    return val2;
 }

loop.bc

--- /dev/fd/63	2023-05-19 09:28:47.484032453 +0000
+++ /dev/fd/62	2023-05-19 09:28:47.484032453 +0000
@@ -6,17 +6,26 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
     var0 = 0U;
     var1 = 0U;
-    while (var1 != 10U)
-        {
-            printf("Variable at %d is ", var1);
-            if (var1 % 2U != 0U) {
+    do {
+        val2 = var1;
+        if (val2 != 10U) {
+            val3 = var1;
+            printf("Variable at %d is ", val3);
+            val4 = var1;
+            if (val4 % 2U != 0U) {
                 printf("odd.\n");
             } else {
                 printf("even.\n");
             }
-            var1 = var1 + 1U;
+            val5 = var1;
+            var1 = val5 + 1U;
         }
+    } while (val2 != 10U);
     return 0U;
 }

float.bc

--- /dev/fd/63	2023-05-19 09:28:47.760038430 +0000
+++ /dev/fd/62	2023-05-19 09:28:47.760038430 +0000
@@ -4,13 +4,21 @@
     unsigned int var0;
     double var1;
     double var2;
+    double val3;
+    float val4;
+    double val5;
+    unsigned int val6;
     var0 = 0U;
     var1 = 3.1428571428571428;
-    var2 = var1 - (double)f;
-    if (var2 >= 0.01) {
+    val3 = var1;
+    val4 = f;
+    var2 = val3 - (double)val4;
+    val5 = var2;
+    if (val5 >= 0.01) {
         var0 = 1U;
     } else {
         var0 = 0U;
     }
-    return var0;
+    val6 = var0;
+    return val6;
 }

nested_while.bc

--- /dev/fd/63	2023-05-19 09:28:47.880041028 +0000
+++ /dev/fd/62	2023-05-19 09:28:47.880041028 +0000
@@ -8,24 +8,42 @@
     unsigned int var0;
     unsigned int var1;
     unsigned int call2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
+    unsigned int val10;
     var0 = 0U;
     call2 = atoi("5");
     var1 = call2;
-    if ((int)var1 > 10) {
-        while ((int)var1 < 20)
-            {
-                var1 = var1 + 1U;
-                printf("loop1 x: %d\n", var1);
+    val3 = var1;
+    if ((int)val3 > 10) {
+        do {
+            val4 = var1;
+            if ((int)val4 < 20) {
+                val5 = var1;
+                var1 = val5 + 1U;
+                val6 = var1;
+                printf("loop1 x: %d\n", val6);
             }
+        } while ((int)val4 < 20);
     }
-    if ((int)var1 >= 20 || (int)var1 <= 10) {
-        while ((int)var1 < 20)
-            {
-                var1 = var1 + 1U;
-                printf("loop2 x: %d\n", var1);
+    if ((int)val4 >= 20 || (int)val3 <= 10) {
+        do {
+            val7 = var1;
+            if ((int)val7 < 20) {
+                val8 = var1;
+                var1 = val8 + 1U;
+                val9 = var1;
+                printf("loop2 x: %d\n", val9);
             }
+        } while ((int)val7 < 20);
     }
-    if (((int)var1 >= 20 || (int)var1 <= 10) && (int)var1 >= 20) {
-        return var0;
+    if ((int)val7 >= 20 && ((int)val4 >= 20 || (int)val3 <= 10)) {
+        val10 = var0;
+        return val10;
     }
 }

vectors.bc

--- /dev/fd/63	2023-05-19 09:28:48.396052201 +0000
+++ /dev/fd/62	2023-05-19 09:28:48.396052201 +0000
@@ -10,15 +10,43 @@
     __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int var5;
     __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int var6;
     void *var7;
+    __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int val8;
+    __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int val9;
+    __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int val10;
+    __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int val11;
+    __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int val12;
+    __attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int val13;
+    void *val14;
+    unsigned int val15;
+    void *val16;
+    unsigned int val17;
+    void *val18;
+    unsigned int val19;
+    void *val20;
+    unsigned int val21;
     var0 = 0U;
     var4 = (__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int){1U, 2U, 3U, 4U};
-    var1 = var4;
+    val8 = var4;
+    var1 = val8;
     var5 = (__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int){};
-    var2 = var5;
+    val9 = var5;
+    var2 = val9;
     var6 = (__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int){4U, 3U, 2U, 1U};
-    var3 = var6;
-    var1 = var1 * var2 + var3;
+    val10 = var6;
+    var3 = val10;
+    val11 = var1;
+    val12 = var2;
+    val13 = var3;
+    var1 = val11 * val12 + val13;
     var7 = &var1;
-    printf("a=[%d %d %d %d]\n", *((unsigned int *)var7), ((unsigned int *)var7)[1UL], ((unsigned int *)var7)[2UL], ((unsigned int *)var7)[3UL]);
+    val14 = var7;
+    val15 = *((unsigned int *)val14);
+    val16 = var7;
+    val17 = ((unsigned int *)val16)[1UL];
+    val18 = var7;
+    val19 = ((unsigned int *)val18)[2UL];
+    val20 = var7;
+    val21 = ((unsigned int *)val20)[3UL];
+    printf("a=[%d %d %d %d]\n", val15, val17, val19, val21);
     return 0U;
 }

funcptr.bc

--- /dev/fd/63	2023-05-19 09:28:48.464053673 +0000
+++ /dev/fd/62	2023-05-19 09:28:48.464053673 +0000
@@ -5,27 +5,39 @@
 unsigned int add(unsigned int arg0, unsigned int arg1) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
     var0 = arg0;
     var1 = arg1;
-    return var0 + var1;
+    val2 = var0;
+    val3 = var1;
+    return val2 + val3;
 }
 unsigned int sub(unsigned int arg0, unsigned int arg1) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
     var0 = arg0;
     var1 = arg1;
-    return var0 - var1;
+    val2 = var0;
+    val3 = var1;
+    return val2 - val3;
 }
 int main(void) {
     unsigned int var0;
     void *var1;
-    unsigned int call2;
+    unsigned int val2;
+    void *val3;
+    unsigned int call4;
     var0 = 0U;
-    if (x == 0U) {
+    val2 = x;
+    if (val2 == 0U) {
         var1 = &sub;
     } else {
         var1 = &add;
     }
-    call2 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
-    return call2;
+    val3 = var1;
+    call4 = ((unsigned int (*)(unsigned int, unsigned int))val3)(2U, 2U);
+    return call4;
 }

struct_swap.bc

--- /dev/fd/63	2023-05-19 09:28:48.592056445 +0000
+++ /dev/fd/62	2023-05-19 09:28:48.592056445 +0000
@@ -7,9 +7,17 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
     var0 = 0U;
-    var1 = *(unsigned int *)(&a);
-    *(unsigned int *)(&a) = a.field1;
-    a.field1 = var1;
-    return *(unsigned int *)(&a);
+    val2 = *(unsigned int *)(&a);
+    var1 = val2;
+    val3 = a.field1;
+    *(unsigned int *)(&a) = val3;
+    val4 = var1;
+    a.field1 = val4;
+    val5 = *(unsigned int *)(&a);
+    return val5;
 }

short.bc

--- /dev/fd/63	2023-05-19 09:28:48.660057917 +0000
+++ /dev/fd/62	2023-05-19 09:28:48.660057917 +0000
@@ -3,8 +3,12 @@
 int main(void) {
     unsigned int var0;
     unsigned short var1;
+    unsigned short val2;
+    unsigned short val3;
     var0 = 0U;
     a = 13U;
-    var1 = a;
-    return (unsigned int)var1;
+    val2 = a;
+    var1 = val2;
+    val3 = var1;
+    return (unsigned int)val3;
 }

issue_325_goto.bc

--- /dev/fd/63	2023-05-19 09:28:48.732059476 +0000
+++ /dev/fd/62	2023-05-19 09:28:48.732059476 +0000
@@ -5,20 +5,32 @@
     unsigned int var1;
     void *var2;
     unsigned int var3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
     var0 = 0U;
     var1 = arg0;
     var2 = arg1;
-    var3 = var1;
-    if (var3 != 1U && (int)var3 > 1) {
+    val4 = var1;
+    var3 = val4;
+    val5 = var3;
+    if (val5 != 1U) {
+        val7 = var3;
+    }
+    if (val5 != 1U && (int)val7 > 1) {
         putchar(53U);
     }
-    if (var3 == 1U) {
+    if (val5 == 1U) {
         putchar(52U);
-        var3 = var3 + 1U;
+        val6 = var3;
+        var3 = val6 + 1U;
     }
-    if (var3 == 1U || (int)var3 <= 1) {
+    if (val5 == 1U || (int)val7 <= 1) {
         putchar(54U);
     }
     putchar(55U);
-    return var0;
+    val8 = var0;
+    return val8;
 }

inttoptr.bc

--- /dev/fd/63	2023-05-19 09:28:48.940063980 +0000
+++ /dev/fd/62	2023-05-19 09:28:48.940063980 +0000
@@ -3,12 +3,18 @@
 int main(void) {
     unsigned int var0;
     void *var1;
+    unsigned long val2;
+    void *val3;
+    unsigned int val4;
     var0 = 0U;
-    var1 = (void *)a;
-    if (var1 == (void *)0U) {
+    val2 = a;
+    var1 = (void *)val2;
+    val3 = var1;
+    if (val3 == (void *)0U) {
         var0 = 0U;
     } else {
         var0 = 42U;
     }
-    return var0;
+    val4 = var0;
+    return val4;
 }

issue_4.bc

--- /dev/fd/63	2023-05-19 09:28:49.068066752 +0000
+++ /dev/fd/62	2023-05-19 09:28:49.068066752 +0000
@@ -5,17 +5,32 @@
     unsigned int var1;
     unsigned int var2;
     unsigned int var3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
+    unsigned int val10;
     var0 = arg0;
     var1 = arg1;
     var2 = 0U;
     var3 = 0U;
-    while (var3 != 42U)
-        {
-            var2 = var2 + var0;
-            var2 = var2 % var1;
-            var3 = var3 + 1U;
+    do {
+        val4 = var3;
+        if (val4 != 42U) {
+            val5 = var0;
+            val6 = var2;
+            var2 = val6 + val5;
+            val7 = var1;
+            val8 = var2;
+            var2 = val8 % val7;
+            val9 = var3;
+            var3 = val9 + 1U;
         }
-    return var2;
+    } while (val4 != 42U);
+    val10 = var2;
+    return val10;
 }
 int main(void) {
     unsigned int var0;

issue_123_uint128_t.bc

--- /dev/fd/63	2023-05-19 09:28:49.248070649 +0000
+++ /dev/fd/62	2023-05-19 09:28:49.248070649 +0000
@@ -3,8 +3,14 @@
 int main(void) {
     unsigned int var0;
     unsigned __int128 var1;
+    unsigned long val2;
+    unsigned __int128 val3;
+    unsigned long val4;
     var0 = 0U;
-    var1 = x;
-    x = var1;
-    return (unsigned int)(x & 255UL);
+    val2 = x;
+    var1 = val2;
+    val3 = var1;
+    x = val3;
+    val4 = x;
+    return (unsigned int)(val4 & 255UL);
 }

fizzbuzz_stateful.bc

--- /dev/fd/63	2023-05-19 09:28:49.316072122 +0000
+++ /dev/fd/62	2023-05-19 09:28:49.316072122 +0000
@@ -8,31 +8,52 @@
 char _str_3[2] = "\n\000";
 void fizzbuzz(void) {
     unsigned int var0;
-    var0 = i;
-    if ((int)i % 3 == 0U) {
+    unsigned int val1;
+    unsigned int val2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    val1 = i;
+    var0 = val1;
+    val2 = i;
+    if ((int)val2 % 3 == 0U) {
         i = 4U;
         printf("fizz");
     }
-    if ((int)i % 5 == 0U) {
+    val3 = i;
+    if ((int)val3 % 5 == 0U) {
         printf("buzz");
     }
-    if ((int)i % 3 != 0U) {
-        if ((int)i % 5 != 0U) {
-            printf("%d", i);
+    val4 = i;
+    if ((int)val4 % 3 != 0U) {
+        val5 = i;
+        if ((int)val5 % 5 != 0U) {
+            val6 = i;
+            printf("%d", val6);
         }
     }
-    i = var0;
+    val7 = var0;
+    i = val7;
     return;
 }
 int main(void) {
     unsigned int var0;
+    unsigned int val1;
+    unsigned int val2;
+    unsigned int val3;
     var0 = 0U;
     i = 1U;
-    while ((int)i < 16)
-        {
+    do {
+        val1 = i;
+        if ((int)val1 < 16) {
             fizzbuzz();
             printf("\n");
-            i = i + 1U;
+            val2 = i;
+            i = val2 + 1U;
         }
-    return var0;
+    } while ((int)val1 < 16);
+    val3 = var0;
+    return val3;
 }

issue_94_strncmp.bc

bool.bc

--- /dev/fd/63	2023-05-19 09:28:49.936085546 +0000
+++ /dev/fd/62	2023-05-19 09:28:49.936085546 +0000
@@ -3,11 +3,17 @@
 unsigned long b = 1UL;
 int main(void) {
     unsigned int var0;
+    unsigned long val1;
+    unsigned long val2;
+    unsigned int val3;
     var0 = 0U;
-    if ((unsigned int)(a == b) != 0U) {
+    val1 = a;
+    val2 = b;
+    if ((unsigned int)(val1 == val2) != 0U) {
         var0 = 1U;
     } else {
         var0 = 0U;
     }
-    return var0;
+    val3 = var0;
+    return val3;
 }

zext.bc

--- /dev/fd/63	2023-05-19 09:28:50.064088318 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.064088318 +0000
@@ -2,6 +2,8 @@
 char a = (unsigned char)1U;
 int main(void) {
     unsigned int var0;
+    char val1;
     var0 = 0U;
-    return (unsigned int)a;
+    val1 = a;
+    return (unsigned int)val1;
 }

byval_struct.bc

--- /dev/fd/63	2023-05-19 09:28:50.128089704 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.128089704 +0000
@@ -14,9 +14,13 @@
 char _str_3[2] = "4\000";
 char _str_4[11] = "%lld %lld\n\000";
 unsigned long get_3x(struct struct_foo arg0) {
+    unsigned long val0;
+    unsigned long val1;
     void *arg0_ptr = &arg0;
-    ((struct struct_foo *)arg0_ptr)->field0 = ((struct struct_foo *)arg0_ptr)->field0 * 3UL;
-    return ((struct struct_foo *)arg0_ptr)->field0;
+    val0 = ((struct struct_foo *)arg0_ptr)->field0;
+    ((struct struct_foo *)arg0_ptr)->field0 = val0 * 3UL;
+    val1 = ((struct struct_foo *)arg0_ptr)->field0;
+    return val1;
 }
 int main(void) {
     struct struct_foo var0;
@@ -26,6 +30,8 @@
     unsigned int call4;
     unsigned int call5;
     unsigned long call6;
+    unsigned long val7;
+    unsigned long val8;
     call2 = atoi("1");
     var0.field0 = (long)call2;
     call3 = atoi("2");
@@ -36,6 +42,8 @@
     var0.field3 = (long)call5;
     call6 = get_3x(var0);
     var1 = call6;
-    printf("%lld %lld\n", var0.field0, var1);
+    val7 = var0.field0;
+    val8 = var1;
+    printf("%lld %lld\n", val7, val8);
     return 0U;
 }

func_cond_two_arg.bc

--- /dev/fd/63	2023-05-19 09:28:50.204091349 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.204091349 +0000
@@ -5,19 +5,29 @@
 unsigned int f(unsigned int arg0, unsigned int arg1) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
     var0 = arg0;
     var1 = arg1;
-    return (unsigned int)((int)var0 < (int)var1);
+    val2 = var0;
+    val3 = var1;
+    return (unsigned int)((int)val2 < (int)val3);
 }
 int main(void) {
     unsigned int var0;
-    unsigned int call1;
+    unsigned int val1;
+    unsigned int val2;
+    unsigned int call3;
+    unsigned int val4;
     var0 = 0U;
-    call1 = f(x, y);
-    if (call1 == 0U) {
+    val1 = x;
+    val2 = y;
+    call3 = f(val1, val2);
+    if (call3 == 0U) {
         var0 = 0U;
     } else {
         var0 = 1U;
     }
-    return var0;
+    val4 = var0;
+    return val4;
 }

conflicting_global.bc

--- /dev/fd/63	2023-05-19 09:28:50.336094208 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.336094208 +0000
@@ -4,8 +4,12 @@
 char _str[4] = "%d\n\000";
 int main(void) {
     unsigned int var0;
+    unsigned int val1;
+    unsigned int val2;
     var0 = 4U;
-    printf("%d\n", var0);
-    printf("%d\n", a);
+    val1 = var0;
+    printf("%d\n", val1);
+    val2 = a;
+    printf("%d\n", val2);
     return 0U;
 }

assert.bc

--- /dev/fd/63	2023-05-19 09:28:50.404095680 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.404095680 +0000
@@ -8,14 +8,26 @@
 char _str_3[7] = "a % 15\000";
 int main(void) {
     unsigned int var0;
+    unsigned long val1;
+    unsigned long val2;
+    unsigned long val3;
     var0 = 0U;
-    if (a % 3UL == 0UL) {
+    val1 = a;
+    if (val1 % 3UL == 0UL) {
         __assert_fail("a % 3", "assert.c", 6U, "int main(void)");
-    } else if (a % 7UL == 0UL) {
+    } else {
+        val2 = a;
+    }
+    if (val1 % 3UL != 0UL && val2 % 7UL == 0UL) {
         __assert_fail("a % 7", "assert.c", 7U, "int main(void)");
-    } else if (a % 15UL == 0UL) {
+    }
+    if (val1 % 3UL != 0UL && val2 % 7UL != 0UL) {
+        val3 = a;
+    }
+    if (val1 % 3UL != 0UL && val2 % 7UL != 0UL && val3 % 15UL == 0UL) {
         __assert_fail("a % 15", "assert.c", 8U, "int main(void)");
-    } else {
+    }
+    if (val1 % 3UL != 0UL && val2 % 7UL != 0UL && val3 % 15UL != 0UL) {
         return 0U;
     }
 }

switch.bc

--- /dev/fd/63	2023-05-19 09:28:50.668101396 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.668101396 +0000
@@ -3,9 +3,12 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
     var0 = 0U;
     var1 = 0U;
-    switch (a) {
+    val2 = a;
+    switch (val2) {
       default:
         {
             var1 = 255U;
@@ -27,5 +30,6 @@
         }
         break;
     }
-    return var1;
+    val3 = var1;
+    return val3;
 }

branch.bc

--- /dev/fd/63	2023-05-19 09:28:50.816104601 +0000
+++ /dev/fd/62	2023-05-19 09:28:50.816104601 +0000
@@ -11,19 +11,29 @@
     unsigned int var0;
     unsigned long var1;
     unsigned long var2;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned long val5;
+    unsigned int val6;
+    unsigned long val7;
     var0 = 0U;
     var1 = (unsigned long)(&a);
     var2 = (unsigned long)(&c);
-    if (c == 0U) {
-        printf("Global variable 'c' of value %u is at ", c);
-        if (var2 % 2UL != 0UL) {
+    val3 = c;
+    if (val3 == 0U) {
+        val6 = c;
+        printf("Global variable 'c' of value %u is at ", val6);
+        val7 = var2;
+        if (val7 % 2UL != 0UL) {
             printf("odd ");
         } else {
             printf("even ");
         }
     } else {
-        printf("Global variable 'a' of value %u is at ", a);
-        if (var1 % 2UL != 0UL) {
+        val4 = a;
+        printf("Global variable 'a' of value %u is at ", val4);
+        val5 = var1;
+        if (val5 % 2UL != 0UL) {
             printf("odd ");
         } else {
             printf("even ");

template_parameter_pack.bc

--- /dev/fd/63	2023-05-19 09:28:51.224113435 +0000
+++ /dev/fd/62	2023-05-19 09:28:51.224113435 +0000
@@ -17,43 +17,71 @@
     unsigned int var2;
     unsigned int var3;
     unsigned int var4;
-    unsigned int call5;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int val8;
+    unsigned int val9;
+    unsigned int call10;
     var0 = arg0;
     var1 = arg1;
     var2 = arg2;
     var3 = arg3;
     var4 = arg4;
-    call5 = _Z3sumIiJiiiEET_S0_DpT0_(var1, var2, var3, var4);
-    return var0 + call5;
+    val5 = var0;
+    val6 = var1;
+    val7 = var2;
+    val8 = var3;
+    val9 = var4;
+    call10 = _Z3sumIiJiiiEET_S0_DpT0_(val6, val7, val8, val9);
+    return val5 + call10;
 }
 unsigned int _Z3sumIiJiiiEET_S0_DpT0_(unsigned int arg0, unsigned int arg1, unsigned int arg2, unsigned int arg3) {
     unsigned int var0;
     unsigned int var1;
     unsigned int var2;
     unsigned int var3;
-    unsigned int call4;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int val6;
+    unsigned int val7;
+    unsigned int call8;
     var0 = arg0;
     var1 = arg1;
     var2 = arg2;
     var3 = arg3;
-    call4 = _Z3sumIiJiiEET_S0_DpT0_(var1, var2, var3);
-    return var0 + call4;
+    val4 = var0;
+    val5 = var1;
+    val6 = var2;
+    val7 = var3;
+    call8 = _Z3sumIiJiiEET_S0_DpT0_(val5, val6, val7);
+    return val4 + call8;
 }
 unsigned int _Z3sumIiJiiEET_S0_DpT0_(unsigned int arg0, unsigned int arg1, unsigned int arg2) {
     unsigned int var0;
     unsigned int var1;
     unsigned int var2;
-    unsigned int call3;
+    unsigned int val3;
+    unsigned int val4;
+    unsigned int val5;
+    unsigned int call6;
     var0 = arg0;
     var1 = arg1;
     var2 = arg2;
-    call3 = _Z3sumIiET_S0_S0_(var1, var2);
-    return var0 + call3;
+    val3 = var0;
+    val4 = var1;
+    val5 = var2;
+    call6 = _Z3sumIiET_S0_S0_(val4, val5);
+    return val3 + call6;
 }
 unsigned int _Z3sumIiET_S0_S0_(unsigned int arg0, unsigned int arg1) {
     unsigned int var0;
     unsigned int var1;
+    unsigned int val2;
+    unsigned int val3;
     var0 = arg0;
     var1 = arg1;
-    return var0 + var1;
+    val2 = var0;
+    val3 = var1;
+    return val2 + val3;
 }

byval_tail_nogep.ll

byval_tail_gep.ll

@frabert
Copy link
Collaborator Author

frabert commented May 22, 2023

@surovic Thoughts on this? The fix works (until I figure out why the test fails on Linux O1), but the resulting decompilate is very verbose. At the same time, it's fixable by letting mem2reg remove a bunch of allocas and loads...

@surovic
Copy link
Contributor

surovic commented May 22, 2023

Personally, I would look for a better solution. The output quality regressions using this fix are huge. What do you think is the underlying issue for #325 ?

@frabert
Copy link
Collaborator Author

frabert commented May 22, 2023

The issue is that just tracking the number of uses of an instruction doesn't work.

define i32 @main(i32 noundef %0, ptr noundef %1) #0 {
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  %5 = alloca ptr, align 8
  %6 = alloca i32, align 4
  store i32 0, ptr %3, align 4
  store i32 %0, ptr %4, align 4
  store ptr %1, ptr %5, align 8
  %7 = load i32, ptr %4, align 4
  store i32 %7, ptr %6, align 4
  %8 = load i32, ptr %6, align 4
  %9 = icmp eq i32 %8, 1
  br i1 %9, label %10, label %14

10:                                               ; preds = %2
  %11 = call i32 @putchar(i32 noundef 52)
  %12 = load i32, ptr %6, align 4
  %13 = add nsw i32 %12, 1
  store i32 %13, ptr %6, align 4
  br label %20

14:                                               ; preds = %2
  %15 = load i32, ptr %6, align 4
  %16 = icmp sgt i32 %15, 1
  br i1 %16, label %17, label %19

17:                                               ; preds = %14
  %18 = call i32 @putchar(i32 noundef 53)
  br label %22

19:                                               ; preds = %14
  br label %20

20:                                               ; preds = %19, %10
  %21 = call i32 @putchar(i32 noundef 54)
  br label %22

22:                                               ; preds = %20, %17
  %23 = call i32 @putchar(i32 noundef 55)
  %24 = load i32, ptr %3, align 4
  ret i32 %24
}
int main(int arg0, char **arg1) {
    unsigned int var0;
    unsigned int var1;
    void *var2;
    unsigned int var3;
    var0 = 0U;
    var1 = arg0;
    var2 = arg1;
    var3 = var1;
    if (var3 != 1U && (int)var3 > 1) {
        putchar(0x35U);
    }
    if (var3 == 1U) {
        putchar(0x34U);
        var3 = var3 + 1U;
    }
    if (var3 == 1U || (int)var3 <= 1) {
        putchar(0x36U);
    }
    putchar(0x37U);
    return var0;
}

In this case, the bug would have been fixed if Rellic had created a storage variable for %9, but that didn't happen because it's only used once in the LLVM bitcode, yet its expression (var3 == 1U) is used multiple times during generation. Maybe we can track the number of uses of each instruction while generating the code.

@pgoodman
Copy link
Collaborator

The code checks hasNUsesOrMore(1) on calls and loads. This surprises me; why are those conditional on at least one use at all? Is there some logic somewhere that is able to tell us that these instructions have no side-effects (e.g. the call being pure, or the the load being on an alloca or constant global)?

It seems like the underlying problem that the hasNUsesOrMore is trying to solve is to help fake the maintenance of the existing partial order among calls, loads, and stores induced by the control-flow graph (ignoring back-edges).

@frabert
Copy link
Collaborator Author

frabert commented May 23, 2023

In a sense, that is true. The issue is that Rellic's codegen is not order-preserving, so we need to "snapshot" the value of instructions that have potential side-effects at the moment they are evaluated.

Re: logic that discovers if instructions are free of side effects

I'm not aware of such mechanism being already available in LLVM, but cooking up something ad-hoc for our specific use case seems feasible

Re: conditionals

For calls, it's so we cache the return value of function calls in case they are used elsewhere, while still keeping calls that do not return stuff on their own. For loads, I'd say it's a bug introduced by yours truly :)

@pgoodman
Copy link
Collaborator

Is there a way to encode the partial order relation as Z3 expressions? That is, could loads be somehow turned into uninterpreted function calls that return a tuple, where one element is the value returned, and the other is a "memory token" (think Remill's memory pointer). Then you could even fake a phi node in z3 if you needed to merge multiple tokens.

@frabert
Copy link
Collaborator Author

frabert commented May 24, 2023

I'm not sure what that would look like. Could you make a quick example?

@pgoodman
Copy link
Collaborator

Define a new LLVM function with prototype roughly

ptr __ptr(ptr, ptr)

Transform loads as follows:

%x = load %y

Into:

%MEMORY = alloca ptr
...
%y_memory = load ptr %MEMORY
%y1 = call __ptr(%y, %y_memory)
store %y1, %MEMORY
%x = load %y1

Or possibly define __ptr as: ptr __ptr(ptr, ...) and "mix in" the loaded values themselves, to really enforce ordering:

%y_memory = load ptr %MEMORY
%y1 = call __ptr(%y, %y_memory)
%x = load %y1
%y2 = call __ptr(%y1, %x)
store %y2, %MEMORY

Then run mem2reg on this to eliminate the %MEMORY alloca, then add custom lift logic to ignore __ptr, or always lift it as an NullStmt or something like that. The "something like that" is load bearing here; I don't know how precisely you represent this as ASTs so that is both "there" but "not there."

On the assumption that the above is viable, I predict two kinds of contention with this approach:

  1. This changes the bitcode.
  2. This introduces an ad hoc, informally specified dialect into the bitcode.

The latter is a stronger argument against this approach, but I think that argument fails at the point that the whole process Rellic goes through is a bunch of unspecified dialects of Clang ASTs. I recall that intermediate stages of Rellic's procedures produce code that is not valid, and requires some simplification to eliminate issues. The former is a means to an end, like running mem2reg before Rellic, which practically all uses cases do anyway, so I don't think it's really a reasonable blocker.

@frabert
Copy link
Collaborator Author

frabert commented May 25, 2023

Honestly I'm not convinced this approach is going to be particularly better or easier to implement than tracking the usage of loads more accurately.

This seems to be introducing complexity to the "preprocessing stage" that can potentially make debugging additional issues more difficuly (more levels of indirection), and it seems to be solving the issue by basically turning loads into calls (which we currently handle correctly, as far as we know at least) but would introduce lots of auxiliary variables as well

@github-actions
Copy link

See the diff generated by this PR for the tests here: https://github.com/lifting-bits/rellic/actions/runs/5133502124

fizzbuzz.bc

--- /dev/fd/63	2023-05-31 13:40:14.949662094 +0000
+++ /dev/fd/62	2023-05-31 13:40:14.949662094 +0000
@@ -7,13 +7,25 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
+    unsigned char br_cond_6;
     var0 = 0U;
     var1 = 0U;
-    while ((int)var1 < 30)
-        {
-            if ((int)var1 % 5 != 0U || (int)var1 % 3 != 0U) {
-                if ((int)var1 % 3 != 0U) {
-                    if ((int)var1 % 5 != 0U) {
+    do {
+        br_cond_2 = (int)var1 < 30;
+        if (br_cond_2) {
+            br_cond_3 = (int)var1 % 3 == 0U;
+            if (br_cond_3) {
+                br_cond_4 = (int)var1 % 5 == 0U;
+            }
+            if (!br_cond_4 || !br_cond_3) {
+                br_cond_5 = (int)var1 % 3 == 0U;
+                if (!br_cond_5) {
+                    br_cond_6 = (int)var1 % 5 == 0U;
+                    if (!br_cond_6) {
                         printf("%d\n", var1);
                     } else {
                         printf("buzz\n");
@@ -26,5 +38,6 @@
             }
             var1 = var1 + 1U;
         }
+    } while (br_cond_2);
     return var0;
 }

typedefs_of_typedefs.bc

switch_loop.bc

func_cond_zero_arg.bc

--- /dev/fd/63	2023-05-31 13:40:16.325684658 +0000
+++ /dev/fd/62	2023-05-31 13:40:16.325684658 +0000
@@ -8,9 +8,11 @@
 int main(void) {
     unsigned int var0;
     unsigned int call1;
+    unsigned char br_cond_2;
     var0 = 0U;
     call1 = f();
-    if (call1 == 0U) {
+    br_cond_2 = call1 != 0U;
+    if (!br_cond_2) {
         var0 = 0U;
     } else {
         var0 = 1U;

fcmp.bc

conflicting_names.bc

--- /dev/fd/63	2023-05-31 13:40:16.549688331 +0000
+++ /dev/fd/62	2023-05-31 13:40:16.549688331 +0000
@@ -20,18 +20,22 @@
     unsigned int var4;
     unsigned int var5;
     unsigned int var6;
-    unsigned int call7;
+    unsigned char br_cond_7;
+    unsigned int call8;
+    unsigned char br_cond_9;
     var0 = 0U;
     var1 = 0U;
     var2 = (void *)0U;
     var3 = 0U;
-    if (1 >= (int)var1) {
+    br_cond_7 = 1 < (int)var1;
+    if (!br_cond_7) {
         var6 = 1U;
         var3 = var6;
     } else {
-        call7 = atoi(((void **)var2)[1UL]);
-        var4 = call7;
-        if ((int)var4 > 10) {
+        call8 = atoi(((void **)var2)[1UL]);
+        var4 = call8;
+        br_cond_9 = (int)var4 > 10;
+        if (br_cond_9) {
             var5 = 99U;
             var3 = var5;
         }

struct.bc

--- /dev/fd/63	2023-05-31 13:40:16.757691742 +0000
+++ /dev/fd/62	2023-05-31 13:40:16.757691742 +0000
@@ -6,8 +6,10 @@
 struct struct__pair a = {0U, 42U};
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
-    if (*(unsigned int *)(&a) == 0U) {
+    br_cond_1 = *(unsigned int *)(&a) != 0U;
+    if (!br_cond_1) {
         var0 = a.field1;
     } else {
         var0 = *(unsigned int *)(&a);

issue_183_literal_structs.bc

zeroinit.bc

--- /dev/fd/63	2023-05-31 13:40:16.981695415 +0000
+++ /dev/fd/62	2023-05-31 13:40:16.981695415 +0000
@@ -16,9 +16,13 @@
 unsigned long a1[256] = {};
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
+    unsigned char br_cond_2;
     var0 = 0U;
-    if (*(unsigned int *)(&r1.field1) == 0U) {
-        if (a1[42UL] == 0UL) {
+    br_cond_1 = *(unsigned int *)(&r1.field1) != 0U;
+    if (!br_cond_1) {
+        br_cond_2 = a1[42UL] != 0UL;
+        if (!br_cond_2) {
             var0 = 0U;
         } else {
             var0 = 2U;

issue_127_uint128_t_lit.bc

global_using_function_decl.bc

init_list.bc

reg_test_structure_fields.bc

ret0.bc

goto_loop.bc

--- /dev/fd/63	2023-05-31 13:40:17.585705320 +0000
+++ /dev/fd/62	2023-05-31 13:40:17.585705320 +0000
@@ -4,21 +4,30 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
     var0 = 0U;
     var1 = 0U;
     while (1U)
         {
             var1 = var1 + 1U;
-            if (var1 == 1U) {
+            br_cond_2 = var1 == 1U;
+            if (br_cond_2) {
                 printf("%d\n", var1);
-            } else if (var1 != 2U) {
-                break;
             } else {
+                br_cond_3 = var1 == 2U;
+            }
+            if (!br_cond_2 && !br_cond_3) {
+                break;
+            }
+            if (!br_cond_2 && br_cond_3) {
                 printf("%d\n", var1);
             }
         }
-    if (var1 != 1U && var1 != 2U) {
-        if (var1 == 3U) {
+    if (!br_cond_2 && !br_cond_3) {
+        br_cond_4 = var1 == 3U;
+        if (br_cond_4) {
             printf("%d\n", var1);
         }
         return var0;

trunc.bc

bitops.bc

--- /dev/fd/63	2023-05-31 13:40:18.021712470 +0000
+++ /dev/fd/62	2023-05-31 13:40:18.025712535 +0000
@@ -4,14 +4,20 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
     var0 = 0U;
     var1 = 0U;
-    if (((int)a >> b & 1U) != 0U) {
+    br_cond_2 = ((int)a >> b & 1U) != 0U;
+    if (br_cond_2) {
         var1 = var1 + 1U;
     }
-    if ((a >> b ^ 1U) != 0U) {
+    br_cond_3 = (a >> b ^ 1U) != 0U;
+    if (br_cond_3) {
         var1 = var1 + 2U;
     }
+    br_cond_4 = a << b != 0U;
     var1 = var1 + 3U;
     return var1;
 }

cast.bc

nullptr.bc

--- /dev/fd/63	2023-05-31 13:40:18.317717324 +0000
+++ /dev/fd/62	2023-05-31 13:40:18.317717324 +0000
@@ -2,8 +2,10 @@
 void *ptr = (void *)0U;
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
-    if (ptr != (void *)0U) {
+    br_cond_1 = ptr == (void *)0U;
+    if (!br_cond_1) {
         var0 = 1U;
     } else {
         var0 = 0U;

nested_struct.bc

array_swap.bc

binops.bc

--- /dev/fd/63	2023-05-31 13:40:18.605722046 +0000
+++ /dev/fd/62	2023-05-31 13:40:18.605722046 +0000
@@ -4,12 +4,18 @@
     unsigned int var0;
     unsigned int var1;
     unsigned int var2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = arg0;
     var1 = var0 % 4U;
     var2 = 0U;
-    if (var1 != 0U) {
-        if (var1 != 1U) {
-            if (var1 != 2U) {
+    br_cond_3 = var1 == 0U;
+    if (!br_cond_3) {
+        br_cond_4 = var1 == 1U;
+        if (!br_cond_4) {
+            br_cond_5 = var1 == 2U;
+            if (!br_cond_5) {
                 var2 = (var0 + 3131756735U) * (5U & var0);
             } else {
                 var2 = (var0 ^ 3131756735U) * (4U | var0);

bitmask.bc

--- /dev/fd/63	2023-05-31 13:40:19.077729831 +0000
+++ /dev/fd/62	2023-05-31 13:40:19.077729831 +0000
@@ -2,8 +2,10 @@
 unsigned long a = 43981UL;
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
-    if ((a & 4080UL) >> 4UL != 188UL) {
+    br_cond_1 = (a & 4080UL) >> 4UL == 188UL;
+    if (!br_cond_1) {
         var0 = 1U;
     } else {
         var0 = 0U;

loop.bc

--- /dev/fd/63	2023-05-31 13:40:19.221732336 +0000
+++ /dev/fd/62	2023-05-31 13:40:19.221732336 +0000
@@ -6,17 +6,22 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
     var1 = 0U;
-    while (var1 != 10U)
-        {
+    do {
+        br_cond_2 = var1 != 10U;
+        if (br_cond_2) {
             printf("Variable at %d is ", var1);
-            if (var1 % 2U != 0U) {
+            br_cond_3 = var1 % 2U == 0U;
+            if (!br_cond_3) {
                 printf("odd.\n");
             } else {
                 printf("even.\n");
             }
             var1 = var1 + 1U;
         }
+    } while (br_cond_2);
     return 0U;
 }

float.bc

--- /dev/fd/63	2023-05-31 13:40:19.557738180 +0000
+++ /dev/fd/62	2023-05-31 13:40:19.557738180 +0000
@@ -4,10 +4,12 @@
     unsigned int var0;
     double var1;
     double var2;
+    unsigned char br_cond_3;
     var0 = 0U;
     var1 = 3.1428571428571428;
     var2 = var1 - (double)f;
-    if (var2 >= 0.01) {
+    br_cond_3 = var2 < 0.01;
+    if (!br_cond_3) {
         var0 = 1U;
     } else {
         var0 = 0U;

nested_while.bc

--- /dev/fd/63	2023-05-31 13:40:19.693740546 +0000
+++ /dev/fd/62	2023-05-31 13:40:19.693740546 +0000
@@ -8,24 +8,32 @@
     unsigned int var0;
     unsigned int var1;
     unsigned int call2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     call2 = atoi("5");
     var1 = call2;
-    if ((int)var1 > 10) {
-        while ((int)var1 < 20)
-            {
+    br_cond_3 = (int)var1 > 10;
+    if (br_cond_3) {
+        do {
+            br_cond_4 = (int)var1 < 20;
+            if (br_cond_4) {
                 var1 = var1 + 1U;
                 printf("loop1 x: %d\n", var1);
             }
+        } while (br_cond_4);
     }
-    if ((int)var1 >= 20 || (int)var1 <= 10) {
-        while ((int)var1 < 20)
-            {
+    if (!br_cond_4 || !br_cond_3) {
+        do {
+            br_cond_5 = (int)var1 < 20;
+            if (br_cond_5) {
                 var1 = var1 + 1U;
                 printf("loop2 x: %d\n", var1);
             }
+        } while (br_cond_5);
     }
-    if ((int)var1 >= 20 && ((int)var1 >= 20 || (int)var1 <= 10)) {
+    if ((!br_cond_4 || !br_cond_3) && !br_cond_5) {
         return var0;
     }
 }

vectors.bc

funcptr.bc

--- /dev/fd/63	2023-05-31 13:40:20.405752932 +0000
+++ /dev/fd/62	2023-05-31 13:40:20.405752932 +0000
@@ -19,13 +19,15 @@
 int main(void) {
     unsigned int var0;
     void *var1;
-    unsigned int call2;
+    unsigned char br_cond_2;
+    unsigned int call3;
     var0 = 0U;
-    if (x == 0U) {
+    br_cond_2 = x != 0U;
+    if (!br_cond_2) {
         var1 = &sub;
     } else {
         var1 = &add;
     }
-    call2 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
-    return call2;
+    call3 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
+    return call3;
 }

struct_swap.bc

short.bc

issue_325_goto.bc

--- /dev/fd/63	2023-05-31 13:40:20.697758011 +0000
+++ /dev/fd/62	2023-05-31 13:40:20.697758011 +0000
@@ -5,18 +5,24 @@
     unsigned int var1;
     void *var2;
     unsigned int var3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     var1 = arg0;
     var2 = arg1;
     var3 = var1;
-    if (var3 != 1U && (int)var3 > 1) {
+    br_cond_4 = var3 == 1U;
+    if (!br_cond_4) {
+        br_cond_5 = (int)var3 > 1;
+    }
+    if (!br_cond_4 && br_cond_5) {
         putchar(53U);
     }
-    if (var3 == 1U) {
+    if (br_cond_4) {
         putchar(52U);
         var3 = var3 + 1U;
     }
-    if (var3 == 1U || (int)var3 <= 1) {
+    if (br_cond_4 || !br_cond_5) {
         putchar(54U);
     }
     putchar(55U);

inttoptr.bc

--- /dev/fd/63	2023-05-31 13:40:20.945762325 +0000
+++ /dev/fd/62	2023-05-31 13:40:20.945762325 +0000
@@ -3,9 +3,11 @@
 int main(void) {
     unsigned int var0;
     void *var1;
+    unsigned char br_cond_2;
     var0 = 0U;
     var1 = (void *)a;
-    if (var1 == (void *)0U) {
+    br_cond_2 = var1 != (void *)0U;
+    if (!br_cond_2) {
         var0 = 0U;
     } else {
         var0 = 42U;

issue_4.bc

--- /dev/fd/63	2023-05-31 13:40:21.085764761 +0000
+++ /dev/fd/62	2023-05-31 13:40:21.085764761 +0000
@@ -5,16 +5,19 @@
     unsigned int var1;
     unsigned int var2;
     unsigned int var3;
+    unsigned char br_cond_4;
     var0 = arg0;
     var1 = arg1;
     var2 = 0U;
     var3 = 0U;
-    while (var3 != 42U)
-        {
+    do {
+        br_cond_4 = var3 != 42U;
+        if (br_cond_4) {
             var2 = var2 + var0;
             var2 = var2 % var1;
             var3 = var3 + 1U;
         }
+    } while (br_cond_4);
     return var2;
 }
 int main(void) {

issue_123_uint128_t.bc

fizzbuzz_stateful.bc

--- /dev/fd/63	2023-05-31 13:40:21.373769771 +0000
+++ /dev/fd/62	2023-05-31 13:40:21.373769771 +0000
@@ -8,16 +8,24 @@
 char _str_3[2] = "\n\000";
 void fizzbuzz(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
     var0 = i;
-    if ((int)i % 3 == 0U) {
+    br_cond_1 = (int)i % 3 == 0U;
+    if (br_cond_1) {
         i = 4U;
         printf("fizz");
     }
-    if ((int)i % 5 == 0U) {
+    br_cond_2 = (int)i % 5 == 0U;
+    if (br_cond_2) {
         printf("buzz");
     }
-    if ((int)i % 3 != 0U) {
-        if ((int)i % 5 != 0U) {
+    br_cond_3 = (int)i % 3 != 0U;
+    if (br_cond_3) {
+        br_cond_4 = (int)i % 5 != 0U;
+        if (br_cond_4) {
             printf("%d", i);
         }
     }
@@ -26,13 +34,16 @@
 }
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
     i = 1U;
-    while ((int)i < 16)
-        {
+    do {
+        br_cond_1 = (int)i < 16;
+        if (br_cond_1) {
             fizzbuzz();
             printf("\n");
             i = i + 1U;
         }
+    } while (br_cond_1);
     return var0;
 }

issue_94_strncmp.bc

--- /dev/fd/63	2023-05-31 13:40:21.857778190 +0000
+++ /dev/fd/62	2023-05-31 13:40:21.857778190 +0000
@@ -12,14 +12,18 @@
     char var1[20];
     char var2[20];
     unsigned int call3;
-    unsigned int call4;
+    unsigned char br_cond_4;
+    unsigned int call5;
+    unsigned char br_cond_6;
     var0 = 0U;
     strcpy(var1, "hello");
     strcpy(var2, "helLO WORLD");
     call3 = strncmp(var1, var2, 3UL);
-    if ((int)call3 <= 0) {
-        call4 = strncmp(var1, var2, 3UL);
-        if ((int)call4 >= 0) {
+    br_cond_4 = (int)call3 > 0;
+    if (!br_cond_4) {
+        call5 = strncmp(var1, var2, 3UL);
+        br_cond_6 = (int)call5 < 0;
+        if (!br_cond_6) {
             printf("Both the strings str1 and str2 are equal");
         } else {
             printf("ASCII value of first unmatched character of str1 is less than str2");

bool.bc

--- /dev/fd/63	2023-05-31 13:40:22.113782643 +0000
+++ /dev/fd/62	2023-05-31 13:40:22.113782643 +0000
@@ -3,8 +3,10 @@
 unsigned long b = 1UL;
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
-    if ((unsigned int)(a == b) != 0U) {
+    br_cond_1 = (unsigned int)(a == b) == 0U;
+    if (!br_cond_1) {
         var0 = 1U;
     } else {
         var0 = 0U;

zext.bc

byval_struct.bc

func_cond_two_arg.bc

--- /dev/fd/63	2023-05-31 13:40:22.409787793 +0000
+++ /dev/fd/62	2023-05-31 13:40:22.409787793 +0000
@@ -12,9 +12,11 @@
 int main(void) {
     unsigned int var0;
     unsigned int call1;
+    unsigned char br_cond_2;
     var0 = 0U;
     call1 = f(x, y);
-    if (call1 == 0U) {
+    br_cond_2 = call1 != 0U;
+    if (!br_cond_2) {
         var0 = 0U;
     } else {
         var0 = 1U;

conflicting_global.bc

assert.bc

--- /dev/fd/63	2023-05-31 13:40:22.625791550 +0000
+++ /dev/fd/62	2023-05-31 13:40:22.625791550 +0000
@@ -8,14 +8,26 @@
 char _str_3[7] = "a % 15\000";
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
-    if (a % 3UL == 0UL) {
+    br_cond_1 = a % 3UL != 0UL;
+    if (!br_cond_1) {
         __assert_fail("a % 3", "assert.c", 6U, "int main(void)");
-    } else if (a % 7UL == 0UL) {
+    } else {
+        br_cond_2 = a % 7UL != 0UL;
+    }
+    if (br_cond_1 && !br_cond_2) {
         __assert_fail("a % 7", "assert.c", 7U, "int main(void)");
-    } else if (a % 15UL == 0UL) {
+    }
+    if (br_cond_1 && br_cond_2) {
+        br_cond_3 = a % 15UL != 0UL;
+    }
+    if (br_cond_1 && br_cond_2 && !br_cond_3) {
         __assert_fail("a % 15", "assert.c", 8U, "int main(void)");
-    } else {
+    }
+    if (br_cond_1 && br_cond_2 && br_cond_3) {
         return 0U;
     }
 }

switch.bc

branch.bc

--- /dev/fd/63	2023-05-31 13:40:23.093799691 +0000
+++ /dev/fd/62	2023-05-31 13:40:23.097799761 +0000
@@ -11,19 +11,25 @@
     unsigned int var0;
     unsigned long var1;
     unsigned long var2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     var1 = (unsigned long)(&a);
     var2 = (unsigned long)(&c);
-    if (c == 0U) {
+    br_cond_3 = c != 0U;
+    if (!br_cond_3) {
         printf("Global variable 'c' of value %u is at ", c);
-        if (var2 % 2UL != 0UL) {
+        br_cond_5 = var2 % 2UL == 0UL;
+        if (!br_cond_5) {
             printf("odd ");
         } else {
             printf("even ");
         }
     } else {
         printf("Global variable 'a' of value %u is at ", a);
-        if (var1 % 2UL != 0UL) {
+        br_cond_4 = var1 % 2UL == 0UL;
+        if (!br_cond_4) {
             printf("odd ");
         } else {
             printf("even ");

template_parameter_pack.bc

byval_tail_nogep.ll

byval_tail_gep.ll

@github-actions
Copy link

See the diff generated by this PR for the tests here: https://github.com/lifting-bits/rellic/actions/runs/5291994697

fizzbuzz.bc

--- /dev/fd/63	2023-06-16 16:13:31.943651506 +0000
+++ /dev/fd/62	2023-06-16 16:13:31.943651506 +0000
@@ -7,11 +7,17 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
     var1 = 0U;
-    while ((int)var1 < 30)
-        {
-            if ((int)var1 % 5 != 0U || (int)var1 % 3 != 0U) {
+    do {
+        br_cond_2 = (int)var1 < 30;
+        if (br_cond_2) {
+            br_cond_3 = (int)var1 % 3 == 0U;
+            if (br_cond_3) {
+            }
+            if ((int)var1 % 5 != 0U || !br_cond_3) {
                 if ((int)var1 % 3 != 0U) {
                     if ((int)var1 % 5 != 0U) {
                         printf("%d\n", var1);
@@ -26,5 +32,6 @@
             }
             var1 = var1 + 1U;
         }
+    } while (br_cond_2);
     return var0;
 }

typedefs_of_typedefs.bc

switch_loop.bc

func_cond_zero_arg.bc

fcmp.bc

conflicting_names.bc

--- /dev/fd/63	2023-06-16 16:13:33.531661845 +0000
+++ /dev/fd/62	2023-06-16 16:13:33.531661845 +0000
@@ -20,7 +20,7 @@
     unsigned int var4;
     unsigned int var5;
     unsigned int var6;
-    unsigned int call7;
+    unsigned int call8;
     var0 = 0U;
     var1 = 0U;
     var2 = (void *)0U;
@@ -29,8 +29,8 @@
         var6 = 1U;
         var3 = var6;
     } else {
-        call7 = atoi(((void **)var2)[1UL]);
-        var4 = call7;
+        call8 = atoi(((void **)var2)[1UL]);
+        var4 = call8;
         if ((int)var4 > 10) {
             var5 = 99U;
             var3 = var5;

struct.bc

issue_183_literal_structs.bc

struct_swap.bc

init_list.bc

reg_test_structure_fields.bc

ret0.bc

goto_loop.bc

--- /dev/fd/63	2023-06-16 16:13:34.251670742 +0000
+++ /dev/fd/62	2023-06-16 16:13:34.251670742 +0000
@@ -4,20 +4,27 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
     var1 = 0U;
     while (1U)
         {
             var1 = var1 + 1U;
-            if (var1 == 1U) {
+            br_cond_2 = var1 == 1U;
+            if (br_cond_2) {
                 printf("%d\n", var1);
-            } else if (var1 != 2U) {
-                break;
             } else {
+                br_cond_3 = var1 == 2U;
+            }
+            if (!br_cond_2 && !br_cond_3) {
+                break;
+            }
+            if (!br_cond_2 && br_cond_3) {
                 printf("%d\n", var1);
             }
         }
-    if (var1 != 1U && var1 != 2U) {
+    if (!br_cond_2 && !br_cond_3) {
         if (var1 == 3U) {
             printf("%d\n", var1);
         }

bool.bc

bitops.bc

--- /dev/fd/63	2023-06-16 16:13:34.743676822 +0000
+++ /dev/fd/62	2023-06-16 16:13:34.743676822 +0000
@@ -4,6 +4,7 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_4;
     var0 = 0U;
     var1 = 0U;
     if (((int)a >> b & 1U) != 0U) {
@@ -12,6 +13,7 @@
     if ((a >> b ^ 1U) != 0U) {
         var1 = var1 + 2U;
     }
+    br_cond_4 = a << b != 0U;
     var1 = var1 + 3U;
     return var1;
 }

cast.bc

nullptr.bc

conflicting_global.bc

array_swap.bc

bitmask.bc

binops.bc

float.bc

nested_while.bc

--- /dev/fd/63	2023-06-16 16:13:36.007692441 +0000
+++ /dev/fd/62	2023-06-16 16:13:36.007692441 +0000
@@ -8,24 +8,32 @@
     unsigned int var0;
     unsigned int var1;
     unsigned int call2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     call2 = atoi("5");
     var1 = call2;
-    if ((int)var1 > 10) {
-        while ((int)var1 < 20)
-            {
+    br_cond_3 = (int)var1 > 10;
+    if (br_cond_3) {
+        do {
+            br_cond_4 = (int)var1 < 20;
+            if (br_cond_4) {
                 var1 = var1 + 1U;
                 printf("loop1 x: %d\n", var1);
             }
+        } while (br_cond_4);
     }
-    if ((int)var1 >= 20 || (int)var1 <= 10) {
-        while ((int)var1 < 20)
-            {
+    if (!br_cond_4 || !br_cond_3) {
+        do {
+            br_cond_5 = (int)var1 < 20;
+            if (br_cond_5) {
                 var1 = var1 + 1U;
                 printf("loop2 x: %d\n", var1);
             }
+        } while (br_cond_5);
     }
-    if ((int)var1 >= 20 && ((int)var1 >= 20 || (int)var1 <= 10)) {
+    if (!br_cond_5 && (!br_cond_4 || !br_cond_3)) {
         return var0;
     }
 }

zeroinit.bc

funcptr.bc

--- /dev/fd/63	2023-06-16 16:13:36.843702772 +0000
+++ /dev/fd/62	2023-06-16 16:13:36.843702772 +0000
@@ -19,13 +19,13 @@
 int main(void) {
     unsigned int var0;
     void *var1;
-    unsigned int call2;
+    unsigned int call3;
     var0 = 0U;
     if (x == 0U) {
         var1 = &sub;
     } else {
         var1 = &add;
     }
-    call2 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
-    return call2;
+    call3 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
+    return call3;
 }

inttoptr.bc

short.bc

issue_325_goto.bc

--- /dev/fd/63	2023-06-16 16:13:37.211707319 +0000
+++ /dev/fd/62	2023-06-16 16:13:37.211707319 +0000
@@ -5,18 +5,24 @@
     unsigned int var1;
     void *var2;
     unsigned int var3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     var1 = arg0;
     var2 = arg1;
     var3 = var1;
-    if (var3 != 1U && (int)var3 > 1) {
+    br_cond_4 = var3 == 1U;
+    if (!br_cond_4) {
+        br_cond_5 = (int)var3 > 1;
+    }
+    if (!br_cond_4 && br_cond_5) {
         putchar(53U);
     }
-    if (var3 == 1U) {
+    if (br_cond_4) {
         putchar(52U);
         var3 = var3 + 1U;
     }
-    if (var3 == 1U || (int)var3 <= 1) {
+    if (br_cond_4 || !br_cond_5) {
         putchar(54U);
     }
     putchar(55U);

trunc.bc

vectors.bc

issue_4.bc

--- /dev/fd/63	2023-06-16 16:13:37.603711930 +0000
+++ /dev/fd/62	2023-06-16 16:13:37.603711930 +0000
@@ -5,16 +5,19 @@
     unsigned int var1;
     unsigned int var2;
     unsigned int var3;
+    unsigned char br_cond_4;
     var0 = arg0;
     var1 = arg1;
     var2 = 0U;
     var3 = 0U;
-    while (var3 != 42U)
-        {
+    do {
+        br_cond_4 = var3 != 42U;
+        if (br_cond_4) {
             var2 = var2 + var0;
             var2 = var2 % var1;
             var3 = var3 + 1U;
         }
+    } while (br_cond_4);
     return var2;
 }
 int main(void) {

issue_127_uint128_t_lit.bc

issue_123_uint128_t.bc

fizzbuzz_stateful.bc

--- /dev/fd/63	2023-06-16 16:13:37.971715531 +0000
+++ /dev/fd/62	2023-06-16 16:13:37.971715531 +0000
@@ -26,13 +26,16 @@
 }
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
     i = 1U;
-    while ((int)i < 16)
-        {
+    do {
+        br_cond_1 = (int)i < 16;
+        if (br_cond_1) {
             fizzbuzz();
             printf("\n");
             i = i + 1U;
         }
+    } while (br_cond_1);
     return var0;
 }

issue_94_strncmp.bc

--- /dev/fd/63	2023-06-16 16:13:38.471720424 +0000
+++ /dev/fd/62	2023-06-16 16:13:38.471720424 +0000
@@ -12,14 +12,14 @@
     char var1[20];
     char var2[20];
     unsigned int call3;
-    unsigned int call4;
+    unsigned int call5;
     var0 = 0U;
     strcpy(var1, "hello");
     strcpy(var2, "helLO WORLD");
     call3 = strncmp(var1, var2, 3UL);
     if ((int)call3 <= 0) {
-        call4 = strncmp(var1, var2, 3UL);
-        if ((int)call4 >= 0) {
+        call5 = strncmp(var1, var2, 3UL);
+        if ((int)call5 >= 0) {
             printf("Both the strings str1 and str2 are equal");
         } else {
             printf("ASCII value of first unmatched character of str1 is less than str2");

nested_struct.bc

global_using_function_decl.bc

byval_struct.bc

func_cond_two_arg.bc

zext.bc

assert.bc

--- /dev/fd/63	2023-06-16 16:13:39.163727196 +0000
+++ /dev/fd/62	2023-06-16 16:13:39.163727196 +0000
@@ -8,14 +8,26 @@
 char _str_3[7] = "a % 15\000";
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
-    if (a % 3UL == 0UL) {
+    br_cond_1 = a % 3UL != 0UL;
+    if (!br_cond_1) {
         __assert_fail("a % 3", "assert.c", 6U, "int main(void)");
-    } else if (a % 7UL == 0UL) {
+    } else {
+        br_cond_2 = a % 7UL != 0UL;
+    }
+    if (br_cond_1 && !br_cond_2) {
         __assert_fail("a % 7", "assert.c", 7U, "int main(void)");
-    } else if (a % 15UL == 0UL) {
+    }
+    if (br_cond_1 && br_cond_2) {
+        br_cond_3 = a % 15UL != 0UL;
+    }
+    if (br_cond_1 && br_cond_2 && !br_cond_3) {
         __assert_fail("a % 15", "assert.c", 8U, "int main(void)");
-    } else {
+    }
+    if (br_cond_1 && br_cond_2 && br_cond_3) {
         return 0U;
     }
 }

loop.bc

--- /dev/fd/63	2023-06-16 16:13:39.491730406 +0000
+++ /dev/fd/62	2023-06-16 16:13:39.491730406 +0000
@@ -6,10 +6,12 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
     var0 = 0U;
     var1 = 0U;
-    while (var1 != 10U)
-        {
+    do {
+        br_cond_2 = var1 != 10U;
+        if (br_cond_2) {
             printf("Variable at %d is ", var1);
             if (var1 % 2U != 0U) {
                 printf("odd.\n");
@@ -18,5 +20,6 @@
             }
             var1 = var1 + 1U;
         }
+    } while (br_cond_2);
     return 0U;
 }

switch.bc

branch.bc

template_parameter_pack.bc

byval_tail_gep.ll

byval_tail_nogep.ll

@github-actions
Copy link

See the diff generated by this PR for the tests here: https://github.com/lifting-bits/rellic/actions/runs/5320347390

fizzbuzz.bc

--- /dev/fd/63	2023-06-20 08:37:54.997204240 +0000
+++ /dev/fd/62	2023-06-20 08:37:54.997204240 +0000
@@ -7,11 +7,17 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
     var1 = 0U;
-    while ((int)var1 < 30)
-        {
-            if ((int)var1 % 5 != 0U || (int)var1 % 3 != 0U) {
+    do {
+        br_cond_2 = (int)var1 < 30;
+        if (br_cond_2) {
+            br_cond_3 = (int)var1 % 3 == 0U;
+            if (br_cond_3) {
+            }
+            if ((int)var1 % 5 != 0U || !br_cond_3) {
                 if ((int)var1 % 3 != 0U) {
                     if ((int)var1 % 5 != 0U) {
                         printf("%d\n", var1);
@@ -26,5 +32,6 @@
             }
             var1 = var1 + 1U;
         }
+    } while (br_cond_2);
     return var0;
 }

typedefs_of_typedefs.bc

switch_loop.bc

func_cond_zero_arg.bc

fcmp.bc

conflicting_names.bc

--- /dev/fd/63	2023-06-20 08:37:56.425223048 +0000
+++ /dev/fd/62	2023-06-20 08:37:56.425223048 +0000
@@ -20,7 +20,7 @@
     unsigned int var4;
     unsigned int var5;
     unsigned int var6;
-    unsigned int call7;
+    unsigned int call8;
     var0 = 0U;
     var1 = 0U;
     var2 = (void *)0U;
@@ -29,8 +29,8 @@
         var6 = 1U;
         var3 = var6;
     } else {
-        call7 = atoi(((void **)var2)[1UL]);
-        var4 = call7;
+        call8 = atoi(((void **)var2)[1UL]);
+        var4 = call8;
         if ((int)var4 > 10) {
             var5 = 99U;
             var3 = var5;

struct.bc

issue_183_literal_structs.bc

zeroinit.bc

issue_127_uint128_t_lit.bc

struct_swap.bc

global_using_function_decl.bc

init_list.bc

reg_test_structure_fields.bc

ret0.bc

bool.bc

bitops.bc

--- /dev/fd/63	2023-06-20 08:37:57.557237958 +0000
+++ /dev/fd/62	2023-06-20 08:37:57.557237958 +0000
@@ -4,6 +4,7 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_4;
     var0 = 0U;
     var1 = 0U;
     if (((int)a >> b & 1U) != 0U) {
@@ -12,6 +13,7 @@
     if ((a >> b ^ 1U) != 0U) {
         var1 = var1 + 2U;
     }
+    br_cond_4 = a << b != 0U;
     var1 = var1 + 3U;
     return var1;
 }

cast.bc

nullptr.bc

conflicting_global.bc

array_swap.bc

binops.bc

bitmask.bc

loop.bc

--- /dev/fd/63	2023-06-20 08:37:58.601251708 +0000
+++ /dev/fd/62	2023-06-20 08:37:58.601251708 +0000
@@ -6,10 +6,12 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
     var0 = 0U;
     var1 = 0U;
-    while (var1 != 10U)
-        {
+    do {
+        br_cond_2 = var1 != 10U;
+        if (br_cond_2) {
             printf("Variable at %d is ", var1);
             if (var1 % 2U != 0U) {
                 printf("odd.\n");
@@ -18,5 +20,6 @@
             }
             var1 = var1 + 1U;
         }
+    } while (br_cond_2);
     return 0U;
 }

float.bc

vectors.bc

funcptr.bc

--- /dev/fd/63	2023-06-20 08:37:59.077257978 +0000
+++ /dev/fd/62	2023-06-20 08:37:59.077257978 +0000
@@ -19,13 +19,13 @@
 int main(void) {
     unsigned int var0;
     void *var1;
-    unsigned int call2;
+    unsigned int call3;
     var0 = 0U;
     if (x == 0U) {
         var1 = &sub;
     } else {
         var1 = &add;
     }
-    call2 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
-    return call2;
+    call3 = ((unsigned int (*)(unsigned int, unsigned int))var1)(2U, 2U);
+    return call3;
 }

goto_loop.bc

--- /dev/fd/63	2023-06-20 08:37:59.209259716 +0000
+++ /dev/fd/62	2023-06-20 08:37:59.209259716 +0000
@@ -4,20 +4,27 @@
 int main(void) {
     unsigned int var0;
     unsigned int var1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
     var1 = 0U;
     while (1U)
         {
             var1 = var1 + 1U;
-            if (var1 == 1U) {
+            br_cond_2 = var1 == 1U;
+            if (br_cond_2) {
                 printf("%d\n", var1);
-            } else if (var1 != 2U) {
-                break;
             } else {
+                br_cond_3 = var1 == 2U;
+            }
+            if (!br_cond_2 && !br_cond_3) {
+                break;
+            }
+            if (!br_cond_2 && br_cond_3) {
                 printf("%d\n", var1);
             }
         }
-    if (var1 != 1U && var1 != 2U) {
+    if (!br_cond_2 && !br_cond_3) {
         if (var1 == 3U) {
             printf("%d\n", var1);
         }

short.bc

issue_325_goto.bc

--- /dev/fd/63	2023-06-20 08:37:59.597264827 +0000
+++ /dev/fd/62	2023-06-20 08:37:59.597264827 +0000
@@ -5,18 +5,24 @@
     unsigned int var1;
     void *var2;
     unsigned int var3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     var1 = arg0;
     var2 = arg1;
     var3 = var1;
-    if (var3 != 1U && (int)var3 > 1) {
+    br_cond_4 = var3 == 1U;
+    if (!br_cond_4) {
+        br_cond_5 = (int)var3 > 1;
+    }
+    if (!br_cond_4 && br_cond_5) {
         putchar(53U);
     }
-    if (var3 == 1U) {
+    if (br_cond_4) {
         putchar(52U);
         var3 = var3 + 1U;
     }
-    if (var3 == 1U || (int)var3 <= 1) {
+    if (br_cond_4 || !br_cond_5) {
         putchar(54U);
     }
     putchar(55U);

trunc.bc

inttoptr.bc

issue_4.bc

--- /dev/fd/63	2023-06-20 08:38:00.013270306 +0000
+++ /dev/fd/62	2023-06-20 08:38:00.013270306 +0000
@@ -5,16 +5,19 @@
     unsigned int var1;
     unsigned int var2;
     unsigned int var3;
+    unsigned char br_cond_4;
     var0 = arg0;
     var1 = arg1;
     var2 = 0U;
     var3 = 0U;
-    while (var3 != 42U)
-        {
+    do {
+        br_cond_4 = var3 != 42U;
+        if (br_cond_4) {
             var2 = var2 + var0;
             var2 = var2 % var1;
             var3 = var3 + 1U;
         }
+    } while (br_cond_4);
     return var2;
 }
 int main(void) {

issue_123_uint128_t.bc

fizzbuzz_stateful.bc

--- /dev/fd/63	2023-06-20 08:38:00.277273783 +0000
+++ /dev/fd/62	2023-06-20 08:38:00.277273783 +0000
@@ -26,13 +26,16 @@
 }
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
     var0 = 0U;
     i = 1U;
-    while ((int)i < 16)
-        {
+    do {
+        br_cond_1 = (int)i < 16;
+        if (br_cond_1) {
             fizzbuzz();
             printf("\n");
             i = i + 1U;
         }
+    } while (br_cond_1);
     return var0;
 }

issue_94_strncmp.bc

--- /dev/fd/63	2023-06-20 08:38:00.717279402 +0000
+++ /dev/fd/62	2023-06-20 08:38:00.717279402 +0000
@@ -12,14 +12,14 @@
     char var1[20];
     char var2[20];
     unsigned int call3;
-    unsigned int call4;
+    unsigned int call5;
     var0 = 0U;
     strcpy(var1, "hello");
     strcpy(var2, "helLO WORLD");
     call3 = strncmp(var1, var2, 3UL);
     if ((int)call3 <= 0) {
-        call4 = strncmp(var1, var2, 3UL);
-        if ((int)call4 >= 0) {
+        call5 = strncmp(var1, var2, 3UL);
+        if ((int)call5 >= 0) {
             printf("Both the strings str1 and str2 are equal");
         } else {
             printf("ASCII value of first unmatched character of str1 is less than str2");

nested_struct.bc

zext.bc

byval_struct.bc

nested_while.bc

--- /dev/fd/63	2023-06-20 08:38:01.149284917 +0000
+++ /dev/fd/62	2023-06-20 08:38:01.149284917 +0000
@@ -8,24 +8,32 @@
     unsigned int var0;
     unsigned int var1;
     unsigned int call2;
+    unsigned char br_cond_3;
+    unsigned char br_cond_4;
+    unsigned char br_cond_5;
     var0 = 0U;
     call2 = atoi("5");
     var1 = call2;
-    if ((int)var1 > 10) {
-        while ((int)var1 < 20)
-            {
+    br_cond_3 = (int)var1 > 10;
+    if (br_cond_3) {
+        do {
+            br_cond_4 = (int)var1 < 20;
+            if (br_cond_4) {
                 var1 = var1 + 1U;
                 printf("loop1 x: %d\n", var1);
             }
+        } while (br_cond_4);
     }
-    if ((int)var1 >= 20 || (int)var1 <= 10) {
-        while ((int)var1 < 20)
-            {
+    if (!br_cond_4 || !br_cond_3) {
+        do {
+            br_cond_5 = (int)var1 < 20;
+            if (br_cond_5) {
                 var1 = var1 + 1U;
                 printf("loop2 x: %d\n", var1);
             }
+        } while (br_cond_5);
     }
-    if (((int)var1 >= 20 || (int)var1 <= 10) && (int)var1 >= 20) {
+    if (!br_cond_5 && (!br_cond_4 || !br_cond_3)) {
         return var0;
     }
 }

func_cond_two_arg.bc

assert.bc

--- /dev/fd/63	2023-06-20 08:38:01.809293343 +0000
+++ /dev/fd/62	2023-06-20 08:38:01.809293343 +0000
@@ -8,14 +8,26 @@
 char _str_3[7] = "a % 15\000";
 int main(void) {
     unsigned int var0;
+    unsigned char br_cond_1;
+    unsigned char br_cond_2;
+    unsigned char br_cond_3;
     var0 = 0U;
-    if (a % 3UL == 0UL) {
+    br_cond_1 = a % 3UL != 0UL;
+    if (!br_cond_1) {
         __assert_fail("a % 3", "assert.c", 6U, "int main(void)");
-    } else if (a % 7UL == 0UL) {
+    } else {
+        br_cond_2 = a % 7UL != 0UL;
+    }
+    if (br_cond_1 && !br_cond_2) {
         __assert_fail("a % 7", "assert.c", 7U, "int main(void)");
-    } else if (a % 15UL == 0UL) {
+    }
+    if (br_cond_1 && br_cond_2) {
+        br_cond_3 = a % 15UL != 0UL;
+    }
+    if (br_cond_1 && br_cond_2 && !br_cond_3) {
         __assert_fail("a % 15", "assert.c", 8U, "int main(void)");
-    } else {
+    }
+    if (br_cond_1 && br_cond_2 && br_cond_3) {
         return 0U;
     }
 }

switch.bc

branch.bc

template_parameter_pack.bc

byval_tail_gep.ll

byval_tail_nogep.ll

@frabert
Copy link
Collaborator Author

frabert commented Jun 20, 2023

I think the failures on Linux are unrelated to this PR.

void *stdout;
int main(int argc, char **argv) {
    unsigned char br_cond_0;
    unsigned int phi2;
    br_cond_0 = argc == 1U;
    if (!br_cond_0) {
        phi2 = 53U;
    } else {
        putc(52U, stdout);
    }
    if (br_cond_0 || argc <= 1) {
        phi2 = 54U;
    }
    putc(phi2, stdout);
    putc(55U, stdout);
    return 0U;
}

It looks like we're generating a reference to stdout, but that reference should probably be marked extern

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants