llvm/llvm-project

Improve `llvm.ucmp.iN.i1` codegen (specifically the 1-bit inputs case)

Open

#129,401 创建于 2025年3月1日

在 GitHub 查看
 (10 评论) (1 反应) (1 负责人)C++ (10,782 fork)batch import
good first issuellvm:SelectionDAGmissed-optimization

仓库指标

Star
 (26,378 star)
PR 合并指标
 (平均合并 1天 2小时) (30 天内合并 1,000 个 PR)

描述

(Context: I was making a rustc PR and accidentally regressed bool::cmp by having it use llvm.ucmp, thus this bug that it would be nice if ucmp just was smart about it.)

llvm.ucmp.i8.i1(a, b) is actually the same as just zext(a) - zext(b): https://alive2.llvm.org/ce/z/oHq3bh

But today they don't codegen the same: https://llvm.godbolt.org/z/nxWdYhvTo

define noundef range(i8 -1, 2) i8 @src(i1 noundef zeroext %a, i1 noundef zeroext %b) unnamed_addr {
start:
  %0 = call i8 @llvm.ucmp.i8.i1(i1 %a, i1 %b)
  ret i8 %0
}

define noundef range(i8 -1, 2) i8 @tgt(i1 noundef zeroext %a, i1 noundef zeroext %b) unnamed_addr {
start:
  %aa = zext i1 %a to i8
  %bb = zext i1 %b to i8
  %0 = sub nsw i8 %aa, %bb
  ret i8 %0
}

on x64 gives

src:                                    # @src
        cmp     dil, sil
        seta    al
        sbb     al, 0
        ret
tgt:                                    # @tgt
        mov     eax, edi
        sub     al, sil
        ret

I don't know if it's better to InstSimplify the ucmp to sext(b) + zext(a) or to improve the codegen for the i1 case, but either way, it'd be nice if the intrinsic worked optimally for i1 in addition to the wider widths.

EDIT: based on comments below, sound like it'd be better to have the codegen special-case this, rather than optimize it away in the middle-end.

贡献者指南