[llvm] [AArch64] Fold cmp #0 into its definition when the flags feed a CCMP (PR #221858)

Andrew Gaul via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 26 16:32:42 PDT 2026


gaul wrote:

Yes. Existing tests don't change because no AArch64 `.ll` test happens to contain the shape: an `and`/`add`/`sub`/`bic` whose result is compared with zero *and* whose flags are then consumed by a `ccmp`. I grepped for it; the `cmp #0`-after-ALU instances in the suite all feed a branch or a select. The `cmp #0` here is created by the ccmp pass itself when it converts a CBZ/CBNZ head (`SSACCmpConv::convert`), so it only shows up when a same-block ALU def meets a ccmp-eligible CFG triangle, which the pass's own tests don't exercise.

To measure it on real code I built `llc` with and without this patch at the PR's base commit and compiled all 5,244 llvm/clang/clang-tools-extra TUs of a default build at -O3 with both:

- 790 TUs and 1,976 functions change
- 2,725 `cmp Rn, #0` instructions removed (net -2,505 instructions)
- they become 2,269 `tst`, 320 `ands`, 98 `bics`, 16 `adds`, 16 `subs`
- 32 functions grow (+174 total); the one I looked at shrank under the tail-duplication threshold and got duplicated, a layout side effect

Typical diffs:

`IEEEFloat::roundToIntegral` (the `isInfinity()` / `isZero()` early outs):
```diff
 	ldrb	w8, [x0, #20]
-	and	w8, w8, #0x7
-	cmp	w8, #0
+	ands	w8, w8, #0x7
 	ccmp	w8, #3, #4, ne
 	b.ne	LBB41_2
```

`llvm/lib/Support/KnownBits.cpp`:
```diff
 	ldr	x8, [x8]
-	and	x8, x8, x27
-	cmp	x8, #0
+	tst	x8, x27
 	add	w8, w25, #1
 	ccmp	w23, w8, #4, eq
```

`llvm/lib/Support/APInt.cpp`, inner loop:
```diff
 	ldr	x10, [x8]
-	add	x10, x10, #1
+	adds	x10, x10, #1
 	str	x10, [x8], #8
-	cmp	x10, #0
 	ccmp	x11, #0, #4, eq
```

`llvm/lib/Support/Path.cpp`:
```diff
 	ldrb	w10, [x9], #1
-	sub	x8, x8, #1
+	subs	x8, x8, #1
 	stp	x9, x8, [sp, #24]
-	cmp	x8, #0
 	ccmp	w10, w27, #0, ne
```

The earlier numbers in the description (489 occurrences in librustc_driver, 408 in Firefox's XUL) came from scanning shipped binaries for the same `alu; cmp #0; ccmp` sequence.


https://github.com/llvm/llvm-project/pull/221858


More information about the llvm-commits mailing list