51 lines
1.6 KiB
LLVM
51 lines
1.6 KiB
LLVM
; Pin: LowerMUL_I32's strength reductions. A product known to fit 16
|
|
; bits -- a u8 index times a 6-byte record's size, the address math of
|
|
; `sim->spr[idx]` -- is a 16-bit multiply, here shifts and adds
|
|
; ((i << 3) - (i << 1)), not a __umulhisi3 call per access. A 32-bit
|
|
; multiply by a constant of two signed digits (2^N +- 2^M: 6, 10, 12, 24,
|
|
; ...) is two inlined shifts and an add or subtract instead of __mulsi3;
|
|
; a constant of more digits keeps the call.
|
|
;
|
|
; RUN: llc -mtriple=w65816 -O2 < %s | FileCheck %s
|
|
; RUN: env W65816_DISABLE_MUL_SHIFT_ADD=1 llc -mtriple=w65816 -O2 < %s | FileCheck %s --check-prefix=OFF
|
|
|
|
target datalayout = "e-m:e-p:32:16-i16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
|
|
|
|
define zeroext i8 @recordField(ptr %s, i8 zeroext %idx) {
|
|
; CHECK-LABEL: recordField:
|
|
; CHECK-NOT: jsl
|
|
; CHECK: and #0xff
|
|
; CHECK-NEXT: asl a
|
|
; CHECK-NEXT: sta 0x1, s
|
|
; CHECK-NEXT: asl a
|
|
; CHECK-NEXT: asl a
|
|
; CHECK-NEXT: sec
|
|
; CHECK-NEXT: sbc 0x1, s
|
|
; CHECK: lda [0xe0], y
|
|
; CHECK: rtl
|
|
; OFF-LABEL: recordField:
|
|
; OFF: jsl __umulhisi3
|
|
%i = zext i8 %idx to i32
|
|
%rec = getelementptr inbounds [6 x i8], ptr %s, i32 %i
|
|
%f = getelementptr inbounds i8, ptr %rec, i32 2
|
|
%v = load i8, ptr %f, align 1
|
|
ret i8 %v
|
|
}
|
|
|
|
define i32 @longTimes6(i32 %x) {
|
|
; CHECK-LABEL: longTimes6:
|
|
; CHECK-NOT: jsl
|
|
; CHECK: sbc
|
|
; CHECK: rtl
|
|
; OFF-LABEL: longTimes6:
|
|
; OFF: jsl __mulsi3
|
|
%m = mul i32 %x, 6
|
|
ret i32 %m
|
|
}
|
|
|
|
define i32 @longTimes1000(i32 %x) {
|
|
; CHECK-LABEL: longTimes1000:
|
|
; CHECK: jsl __mulsi3
|
|
%m = mul i32 %x, 1000
|
|
ret i32 %m
|
|
}
|