On 7/14/25 10:38 AM, Pierrick Bouvier wrote:
On 7/14/25 8:52 AM, Richard Henderson wrote:
On 7/14/25 09:41, Pierrick Bouvier wrote:
Indeed, clang does not fold the condition "value && kvm_enabled() && !
kvm_arm_sve_supported()". Looks like a missing case.
This code compiles with gcc -O0, but not clang -O0.

extern int f(void);
int main(int argc) {
       if (argc && 0)
           f();
}

As folding is not guaranteed by C standard, I'm not sure it's really possible 
to file a
bug. However, since we rely on this behaviour in other parts, maybe it would be 
better to
rewrite the condition on our side.

It's probably worth filing a missed-optimization type bug, if that's available 
in clang's
reporting system.


Sure, I'll post a bug report on clang repository.

With my compiler hat on, I suspect that GCC generates IR like

     if (argc) {
       if (0) {
         f();
       }
     }

in order to get the short-circuting part of && correct, which Just So Happens 
to fold away
exactly as we wish.

I'm not sure how clang expands the expression such that (x && 0) doesn't fold 
away, but (0
&& x) does, as evidenced by


For gcc, the simple GIMPLE tree is identical for both.

int main (int argc)
{
    int D.2775;

    {
      if (0 != 0) goto <D.2773>; else goto <D.2774>;
      <D.2773>:
      f ();
      <D.2774>:
    }
    D.2775 = 0;
    return D.2775;
}

This is the LLVM IR difference between "(0 && argc)" and "(argc && 0)".

   ; Function Attrs: noinline nounwind optnone uwtable
   define dso_local i32 @main(i32 noundef %0) #0 {
     %2 = alloca i32, align 4
-  %3 = alloca i32, align 4
-  store i32 0, ptr %2, align 4
-  store i32 %0, ptr %3, align 4
-  %4 = load i32, ptr %3, align 4
-  %5 = icmp ne i32 %4, 0
-  br i1 %5, label %6, label %9
-
-6:                                                ; preds = %1
-  br i1 false, label %7, label %9
-
-7:                                                ; preds = %6
-  %8 = call i32 @f()
-  br label %9
-
-9:                                                ; preds = %7, %6, %1
-  %10 = load i32, ptr %2, align 4
-  ret i32 %10
+  store i32 %0, ptr %2, align 4
+  ret i32 0
   }

-declare i32 @f() #1
-

We can see it elides completely the if as expected, given the right
order for expression.
On a side note, the first operand still needs to be evaluated if it has
a side effect (especially a function call), before ensuring the shortcut
properly applies.


For reference, this is the associated bug report:
https://github.com/llvm/llvm-project/issues/148955

+        if (kvm_enabled() && !kvm_arm_sve_supported()) {


r~



Reply via email to