bagel99 / llvm-my66000

This is a fork of the LLVM project. The code in branch my66000 supports Mitch Alsup's MY66000. The code in branch mcore supports the Motorola MCore.
http://llvm.org
Other
2 stars 2 forks source link

p??? instruction #32

Closed tkoenig1 closed 1 year ago

tkoenig1 commented 1 year ago

Another one reduced from Perl.

struct unop {
  struct op *op_first
} * S_ck_dump_entersubop_pm_0;
struct op {
  short : 11;
  short : 1;
  short : 1;
  short : 1;
  short op_moresib : 1
} S_ck_dump_entersubop() {
  if (!((struct unop *)S_ck_dump_entersubop)->op_first->op_moresib)
    S_ck_dump_entersubop_pm_0 = 0;
}

treated with cvise with the script

STEM=Peek
clang -O2 -g -fverbose-asm -c --target=my66000 -O3 -fno-vectorize -fno-slp-vectorize  -emit-llvm -fno-unroll-loops $STEM.i || exit 1
llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $STEM.bc
fgrep 'p???' $STEM.s

gets

      .text
        .file   "Peek.i"
        .file   0 "/home/asdf/PERL/TST" "Peek.i" md5 0x87810edc24735616a1dfab10c019e047
        .globl  S_ck_dump_entersubop            ; -- Begin function S_ck_dump_entersubop
        .p2align        3
        .type   S_ck_dump_entersubop,@function
S_ck_dump_entersubop:                   ; @S_ck_dump_entersubop
.Lfunc_begin0:
        .loc    0 10 0                          ; Peek.i:10:0
        .cfi_sections .debug_frame
        .cfi_startproc
; %bb.0:                                ; %entry
        .loc    0 11 47 prologue_end            ; Peek.i:11:47
        ldd     r1,[ip,S_ck_dump_entersubop]
        .loc    0 11 8 is_stmt 0                ; Peek.i:11:8
        ldub    r1,[r1,1]
.Ltmp0:
        .loc    0 11 7                          ; Peek.i:11:7
        p???    r1,0,F
.Ltmp1:
        .loc    0 12 31 is_stmt 1               ; Peek.i:12:31
        std     #0,[ip,S_ck_dump_entersubop_pm_0]
        mov     r1,#0
.Ltmp2:
        .loc    0 13 1                          ; Peek.i:13:1
        ret

where I do not think that 'p???' is a valid instruction :-)

predicate.zip

tkoenig1 commented 1 year ago

I't also missing a comparison.

Similar, this time from doop.c:

struct sv S_do_trans_invmap_sv;
struct sv {
  int sv_flags
} S_do_trans_invmap() {
  if (!(S_do_trans_invmap_sv.sv_flags & 536870912))
    S_do_trans_invmap_sv.sv_flags |= 20000000;
}

with

STEM=doop
clang -O0 -fverbose-asm -c --target=my66000 -O3 -fno-vectorize -fno-slp-vectorize  -emit-llvm -fno-unroll-loops $STEM.i || exit 1
llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $STEM.bc
fgrep 'p???' $STEM.s

gets

S_do_trans_invmap:                      ; @S_do_trans_invmap
; %bb.0:                                ; %entry
        lduw    r1,[ip,S_do_trans_invmap_sv]
        p???    r1,0,FF
        or      r1,r1,#20000000
        stw     r1,[ip,S_do_trans_invmap_sv]
        mov     r1,#0
        ret
tkoenig1 commented 1 year ago

The last test case also has wrong code in the absence of predicates:

$ cat doop.i
struct sv S_do_trans_invmap_sv;
struct sv {
  int SV_flags
} S_do_trans_invmap() {
  if (!(S_do_trans_invmap_sv.sv_flags & 536870912))
    S_do_trans_invmap_sv.sv_flags |= 20000000;
}
$ clang -Og -fverbose-asm -c --target=my66000 -fno-vectorize -fno-slp-vectorize  -emit-llvm -fno-unroll-loops doop.i
doop.i:3:15: warning: expected ';' at end of declaration list
  int sv_flags
              ^
              ;
doop.i:7:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
2 warnings generated.
$ llc --disable-lsr --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 doop.bc
$ cat doop.s 
        .text
        .file   "doop.i"
        .globl  S_do_trans_invmap               ; -- Begin function S_do_trans_invmap
        .type   S_do_trans_invmap,@function
S_do_trans_invmap:                      ; @S_do_trans_invmap
; %bb.0:                                ; %entry
        lduw    r1,[ip,S_do_trans_invmap_sv]
        bb1     29,r1,.LBB0_2
; %bb.1:                                ; %if.then
        or      r1,r1,#20000000
        stw     r1,[ip,S_do_trans_invmap_sv]
.LBB0_2:                                ; %if.end
        mov     r1,#0
        ret
.Lfunc_end0:
        .size   S_do_trans_invmap, .Lfunc_end0-S_do_trans_invmap
                                        ; -- End function
        .bss
        .globl  S_do_trans_invmap_sv
        .p2align        3
        .type   S_do_trans_invmap_sv,@object
        .size   S_do_trans_invmap_sv, 4
S_do_trans_invmap_sv:
        .space  4
        .ident  "clang version 15.0.0 (https://github.com/bagel99/llvm-my66000.git c66d22534c5a05431beb6fbd7573c66aff89f12b)"
        .section        ".note.GNU-stack","",@progbits
$ 

This misses the comparison against the constant 536870912.

bagel99 commented 1 year ago

Obviously the predicated code is wrong. But I think the non-predicated code is correct. The constant 536870912 is 0x20000000. The "bb1 29,r1,.LBB0_2" jumps around the "or" if bit 29 is set. If bit 29 not set, the "or" is executed.

tkoenig1 commented 1 year ago

Obviously the predicated code is wrong. But I think the non-predicated code is correct. The constant 536870912 is 0x20000000. The "bb1 29,r1,.LBB0_2" jumps around the "or" if bit 29 is set. If bit 29 not set, the "or" is executed.

Jep, you're right.

bagel99 commented 1 year ago

Try again with commit 9f1575dce18acaa0c24c19b657259cd769c3962f

tkoenig1 commented 1 year ago

Yes indeed, this is fixed. Great!