Issue 87836
Summary Over-aggressively optimization on infinite loops affects RISC-V platforms as well
Labels new issue
Assignees
Reporter leonardopsantos
    Not exactly a duplicate of https://github.com/llvm/llvm-project/issues/60622 because that issue specifically mentions x86.

I just hit this issue in RISC-V bare-metal target with `clang 17.0.0`, so most definitively not restricted to x86. My code is fairly similar to the test case above:

```c
#define DO_WAIT 0
#define DO_ACTION 1

int g_lock = DO_WAIT;

void __attribute__((noinline)) worker() {
  for (;;) {

    volatile int i = 0;
    i++;
    g_lock = DO_WAIT;

    while (g_lock != DO_ACTION) {
    }

    i = 0xCAFECAFE;
  }
 return;
}

void dontcallme() {
    volatile int i = 0;
 i++;
}

int main() {
  worker();
  return 0;
}
```

The disassembly for that is:

```asm
worker: # @worker
# %bb.0: # %for.cond
	addi	sp, sp, -16
	sw	zero, 12(sp)
	lw	a0, 12(sp)
	addi	a0, a0, 1
	sw	a0, 12(sp)
.Lfunc_end0:
	.size	worker, .Lfunc_end0-worker
 # -- End function
	.globl	dontcallme # -- Begin function dontcallme
	.p2align	2
	.type	dontcallme,@function
dontcallme: # @dontcallme
# %bb.0: # %entry
	addi	sp, sp, -16
	sw	zero, 12(sp)
	lw	a0, 12(sp)
	addi	a0, a0, 1
	sw	a0, 12(sp)
	addi	sp, sp, 16
	ret
.Lfunc_end1:
	.size	dontcallme, .Lfunc_end1-dontcallme
                                        # -- End function
	.globl	main                            # -- Begin function main
```

There's no control instruction at the end of `worker`, so it just falls through to `dontcallme`. 

I'm baffled as to how can anyone think that's reasonable.

GCC for RISC-V _does the right thing_ and adds a `j`: https://godbolt.org/z/h55bYsdo9

I've tried the `-fsanitize=undefined` flag as suggested [here](https://github.com/llvm/llvm-project/issues/48943#issuecomment-981039980), but that doesn't work: https://godbolt.org/z/aYrqfsca7

The workaround is very counter-intuitive:

```c
    while (g_lock != DO_ACTION) {
        asm volatile("");
 }
```

Yields:

```asm
.LBB0_2: # %while.body
                                        #   Parent Loop BB0_1 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	#APP
	#NO_APP
	lw	a3, %pcrel_lo(.Lpcrel_hi0)(a0)
	bne	a3, a1, .LBB0_2
# %bb.3: # %while.end
                                        # in Loop: Header=BB0_1 Depth=1
	sw	a2, 12(sp)
	j	.LBB0_1
.Lfunc_end0:
	.size	worker, .Lfunc_end0-worker
                                        # -- End function
```

Also here: https://godbolt.org/z/f6Y6qdrMT

I also disagree that https://github.com/llvm/llvm-project/issues/60622, https://github.com/llvm/llvm-project/issues/60419, and https://github.com/llvm/llvm-project/issues/60588 should be closed. Especially because there are no proposed workarounds.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to