diffkemp icon indicating copy to clipboard operation
diffkemp copied to clipboard

`simplifycfg` pass sometimes represents `&&` with `select` instead of `and` instruction

Open PLukas2018 opened this issue 1 year ago • 1 comments

simplifycfg pass (used for simplifying/merging basic blocks) which is part of passes which are used in build-kernel command sometimes represents combined condition with && using select instruction instead of and instruction. This can cause inequality in simple examples like extraction condition to function.

Example to replicate behaviour:

// old version
int foo(int a, int b, int c) {
    if (a < b && a < c) {
        return 0;
    } 
    else return 1;
}
// new version
#include <stdbool.h>
// (edited: should be bool not int)
bool bar(int a, int b, int c) {
    return a < b && a < c;
}

int foo(int a, int b, int c) {
    if (bar(a, b, c)) {
        return 0;
    }
    else return 1;
}

Commands to compare the versions:

# build both version
bin/diffkemp build --clang-append="-O1" --clang-append="-Xclang" --clang-append="-disable-llvm-passes" <path-to-c_file> <build_dir>
# run passes used in build-kernel command (includes simplifycfg)
python3 -c "from diffkemp.llvm_ir.kernel_llvm_source_builder import KernelLlvmSourceBuilder
opt = KernelLlvmSourceBuilder._opt_llvm                                         
opt(<path-to-llvm-file-in-build-dir>)
"
# compare snapshots
bin/diffkemp -vvdd compare --stdout <old_build> <new_build>  

Snippet of output:

; Old version
  %4 = icmp slt i32 %0, %1, !dbg !17
  %5 = icmp slt i32 %0, %2
  %or.cond = and i1 %4, %5, !dbg !19
; New version
  %4 = icmp slt i32 %0, %1, !dbg !18
  %5 = icmp slt i32 %0, %2
  %spec.select = select i1 %4, i1 %5, i1 false, !dbg !19

PLukas2018 avatar Nov 16 '23 05:11 PLukas2018

This should be resolved by #322 (once it is merged)

FrNecas avatar Jun 28 '24 11:06 FrNecas