8000 [AVR] Cherry-pick 17 upstream AVR backend fixes into the Rust LLVM fork by dylanmckay · Pull Request #66 · rust-lang/llvm-project · GitHub
[go: up one dir, main page]

Skip to content

[AVR] Cherry-pick 17 upstream AVR backend fixes into the Rust LLVM fork #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[AVR] Fix miscompilation of zext + add
Code like the following:

    define i32 @foo(i32 %a, i1 zeroext %b) addrspace(1) {
    entry:
      %conv = zext i1 %b to i32
      %add = add nsw i32 %conv, %a
      ret i32 %add
    }

Would compile to the following (incorrect) code:

    foo:
        mov     r18, r20
        clr     r19
        add     r22, r18
        adc     r23, r19
        sbci    r24, 0
        sbci    r25, 0
        ret

Those sbci instructions are clearly wrong, they should have been adc
instructions.

This commit improves codegen to use adc instead:

    foo:
        mov     r18, r20
        clr     r19
        ldi     r20, 0
        ldi     r21, 0
        add     r22, r18
        adc     r23, r19
        adc     r24, r20
        adc     r25, r21
        ret

This code is not optimal (it could be just 5 instructions instead of the
current 9) but at least it doesn't miscompile.

Differential Revision: https://reviews.llvm.org/D78439
  • Loading branch information
aykevl authored and dylanmckay committed Jun 23, 2020
commit bc27c282e13a46ab2e0cf51a3831006347cc4f41
2 changes: 0 additions & 2 deletions llvm/lib/Target/AVR/AVRInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2047,8 +2047,6 @@ def : Pat<(add i16:$src1, imm:$src2),
(SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>;
def : Pat<(addc i16:$src1, imm:$src2),
(SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>;
def : Pat<(adde i16:$src1, imm:$src2),
(SBCIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>;

def : Pat<(add i8:$src1, imm:$src2),
(SUBIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>;
Expand Down
45 changes: 45 additions & 0 deletions llvm/test/CodeGen/AVR/add.ll
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ define i16 @add16_reg_imm_subi(i16 %a) {
ret i16 %result
}

define i16 @add16_reg_reg_zext(i16 %a, i1 zeroext %b) {
; CHECK-LABEL: add16_reg_reg_zext:
; CHECK: mov r18, r22
; CHECK: clr r19
; CHECK: add r24, r18
; CHECK: adc r25, r19
%zext = zext i1 %b to i16
%result = add i16 %a, %zext
ret i16 %result
}

define i32 @add32_reg_reg(i32 %a, i32 %b) {
; CHECK-LABEL: add32_reg_reg:
; CHECK: add r22, r18
Expand All @@ -65,6 +76,21 @@ define i32 @add32_reg_imm(i32 %a) {
ret i32 %result
}

define i32 @add32_reg_reg_zext(i32 %a, i1 zeroext %b) {
; CHECK-LABEL: add32_reg_reg_zext:
; CHECK: mov r18, r20
; CHECK: clr r19
; CHECK: ldi r20, 0
; CHECK: ldi r21, 0
; CHECK: add r22, r18
; CHECK: adc r23, r19
; CHECK: adc r24, r20
; CHECK: adc r25, r21
%zext = zext i1 %b to i32
%result = add i32 %a, %zext
ret i32 %result
}

define i64 @add64_reg_reg(i64 %a, i64 %b) {
; CHECK-LABEL: add64_reg_reg:
; CHECK: add r18, r10
Expand All @@ -91,3 +117,22 @@ define i64 @add64_reg_imm(i64 %a) {
%result = add i64 %a, 5
ret i64 %result
}

define i64 @add64_reg_reg_zext(i64 %a, i1 zeroext %b) {
; CHECK-LABEL: add64_reg_reg_zext:
; CHECK: mov r30, r16
; CHECK: clr r31
; CHECK: ldi r26, 0
; CHECK: ldi r27, 0
; CHECK: add r18, r30
; CHECK: adc r19, r31
; CHECK: adc r20, r26
; CHECK: adc r21, r27
; CHECK: adc r22, r26
; CHECK: adc r23, r27
; CHECK: adc r24, r26
; CHECK: adc r25, r27
%zext = zext i1 %b to i64
%result = add i64 %a, %zext
ret i64 %result
}
0