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.

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


r~


Reply via email to