Minor optimizations.

This commit is contained in:
Scott Duensing 2026-10-17 15:40:15 -05:00
parent 12de7c8a57
commit d626c54e92
5 changed files with 64 additions and 4 deletions

Binary file not shown.

View file

@ -1336,6 +1336,14 @@ SDValue W65816TargetLowering::LowerSELECT_CC(SDValue Op,
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
SDLoc DL(Op); SDLoc DL(Op);
// Both arms the same value: no select. The i32 splits below make these
// -- a 0/1 boolean widened to i32 has 0 in both high halves -- and the
// DAG combiner never sees them, as the legalizer lowers each new i16
// SELECT_CC at once. Left alone, each is a CMP, a branch to the next
// instruction and a spilled PHI.
if (TVal == FVal)
return TVal;
// i32 / i64 SELECT_CC. An i8/i16 result selects straight on the CMP/SBC // i32 / i64 SELECT_CC. An i8/i16 result selects straight on the CMP/SBC
// chain's flags (or on the equivalent i16 compare). An i32 result needs // chain's flags (or on the equivalent i16 compare). An i32 result needs
// two per-half selects and a glue value has only one consumer, so it // two per-half selects and a glue value has only one consumer, so it

View file

@ -50,10 +50,13 @@ def P : W65816Reg<8, "p">, DwarfRegNum<[8]>;
// registers with cheap LDA/STA dp inter-register moves. This // registers with cheap LDA/STA dp inter-register moves. This
// relieves pressure on the single Acc16 register (A) so greedy // relieves pressure on the single Acc16 register (A) so greedy
// regalloc can succeed on functions with multiple simultaneously- // regalloc can succeed on functions with multiple simultaneously-
// live i16 vregs. Caller-save: callees may freely overwrite them, // live i16 vregs. IMG0..IMG7 are caller-save: a call clobbers them,
// so regalloc spills around any call that might touch them. Their // so regalloc spills around any call. IMG8..IMG15 are callee-saved:
// HWEncoding is never emitted (asmprinter translates IMGn references // W65816ImgCalleeSave saves and restores them in any function that
// into LDA/STA dp with the right address). // writes them, and callers keep values in them across calls, so hand
// asm called from C must not overwrite them without doing the same.
// Their HWEncoding is never emitted (asmprinter translates IMGn
// references into LDA/STA dp with the right address).
// //
// Layout: IMG0..IMG7 at $D0..$DE (legacy slot block); IMG8..IMG15 // Layout: IMG0..IMG7 at $D0..$DE (legacy slot block); IMG8..IMG15
// at $C0..$CE. Avoid stepping on user DP allocations below $C0. // at $C0..$CE. Avoid stepping on user DP allocations below $C0.

View file

@ -70,6 +70,7 @@ define i16 @f_fabs_olt(float %x) {
; CHECK-NOT: jsl ; CHECK-NOT: jsl
; CHECK: and #0x7fff ; CHECK: and #0x7fff
; CHECK: cmp #0x4020 ; CHECK: cmp #0x4020
; CHECK-NEXT: lda #0x1
; CHECK-NEXT: bcc ; CHECK-NEXT: bcc
; CHECK: rtl ; CHECK: rtl
%a = call float @llvm.fabs.f32(float %x) %a = call float @llvm.fabs.f32(float %x)
@ -84,6 +85,7 @@ define i16 @f_ogt0(float %x) {
; CHECK: adc #0xffff ; CHECK: adc #0xffff
; CHECK: adc #0xffff ; CHECK: adc #0xffff
; CHECK: cmp #0x7f80 ; CHECK: cmp #0x7f80
; CHECK-NEXT: lda #0x1
; CHECK-NEXT: bcc ; CHECK-NEXT: bcc
; CHECK: rtl ; CHECK: rtl
%c = fcmp ogt float %x, 0.0 %c = fcmp ogt float %x, 0.0

View file

@ -0,0 +1,47 @@
; A select whose two arms are the same value is that value: no compare, no
; branch. A 0/1 boolean widened to i32 (a returned bool, a zext to i32) is
; split into a select per half, and the high half's arms are both 0. The
; legalizer lowers each new i16 SELECT_CC at once, so the DAG combiner's
; same-arms fold never saw it: each one left a second compare of the value,
; a branch to the next instruction and a PHI spilled to a slot.
;
; RUN: llc -mtriple=w65816 -O2 < %s | FileCheck %s
target triple = "w65816"
@keys = external global [60 x i8]
; One compare of the loaded byte, one branch on it.
define zeroext i1 @keyDown(i16 zeroext %key) {
; CHECK-LABEL: keyDown:
; CHECK: lda keys, x
; CHECK: bne .LBB0_3
; CHECK-NOT: b{{eq|ne}}
; CHECK: rtl
entry:
%cmp = icmp ugt i16 %key, 59
br i1 %cmp, label %return, label %if.end
if.end:
%idx = zext nneg i16 %key to i32
%p = getelementptr inbounds i8, ptr @keys, i32 %idx
%v = load i8, ptr %p, align 1
%t = icmp ne i8 %v, 0
br label %return
return:
%r = phi i1 [ %t, %if.end ], [ false, %entry ]
ret i1 %r
}
; The high half is the constant, the low half the one select.
define i32 @isZero32(i16 %a) {
; CHECK-LABEL: isZero32:
; CHECK: beq .LBB1_2
; CHECK-NOT: b{{eq|ne}}
; CHECK: ldx #0x0
; CHECK: rtl
%c = icmp eq i16 %a, 0
%r = zext i1 %c to i32
ret i32 %r
}