1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00
llvm-mirror/test/CodeGen/BPF/32-bit-subreg-peephole-phi-3.ll
John Fastabend d6d187a5b7 [BPF] simplify zero extension with MOV_32_64
The current pattern matching for zext results in the following code snippet
being produced,

  w1 = w0
  r1 <<= 32
  r1 >>= 32

Because BPF implementations require zero extension on 32bit loads this
both adds a few extra unneeded instructions but also makes it a bit
harder for the verifier to track the r1 register bounds. For example in
this verifier trace we see at the end of the snippet R2 offset is unknown.
However, if we track this correctly we see w1 should have the same bounds
as r8. R8 smax is less than U32 max value so a zero extend load should keep
the same value. Adding a max value of 800 (R8=inv(id=0,smax_value=800)) to
an off=0, as seen in R7 should create a max offset of 800. However at the
end of the snippet we note the R2 max offset is 0xffffFFFF.

  R0=inv(id=0,smax_value=800)
  R1_w=inv(id=0,umax_value=2147483647,var_off=(0x0; 0x7fffffff))
  R6=ctx(id=0,off=0,imm=0) R7=map_value(id=0,off=0,ks=4,vs=1600,imm=0)
  R8_w=inv(id=0,smax_value=800,umax_value=4294967295,var_off=(0x0; 0xffffffff))
  R9=inv800 R10=fp0 fp-8=mmmm????
 58: (1c) w9 -= w8
 59: (bc) w1 = w8
 60: (67) r1 <<= 32
 61: (77) r1 >>= 32
 62: (bf) r2 = r7
 63: (0f) r2 += r1
 64: (bf) r1 = r6
 65: (bc) w3 = w9
 66: (b7) r4 = 0
 67: (85) call bpf_get_stack#67
  R0=inv(id=0,smax_value=800)
  R1_w=ctx(id=0,off=0,imm=0)
  R2_w=map_value(id=0,off=0,ks=4,vs=1600,umax_value=4294967295,var_off=(0x0; 0xffffffff))
  R3_w=inv(id=0,umax_value=800,var_off=(0x0; 0x3ff))
  R4_w=inv0 R6=ctx(id=0,off=0,imm=0)
  R7=map_value(id=0,off=0,ks=4,vs=1600,imm=0)
  R8_w=inv(id=0,smax_value=800,umax_value=4294967295,var_off=(0x0; 0xffffffff))
  R9_w=inv(id=0,umax_value=800,var_off=(0x0; 0x3ff))
  R10=fp0 fp-8=mmmm????

After this patch R1 bounds are not smashed by the <<=32 >>=32 shift and we
get correct bounds on R2 umax_value=800.

Further it reduces 3 insns to 1.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>

Differential Revision: https://reviews.llvm.org/D73985
2020-05-27 11:26:39 -07:00

54 lines
1.6 KiB
LLVM

; RUN: llc -O2 -march=bpfel -mcpu=v2 -mattr=+alu32 < %s | FileCheck %s
;
; For the below example, two phi node in the loop may depend on
; each other. So implementation must handle recursion properly.
;
; int test(unsigned long a, unsigned long b, unsigned long c) {
; int val = 0;
;
; #pragma clang loop unroll(disable)
; for (long i = 0; i < 100; i++) {
; if (a > b)
; val = 1;
; a += b;
; if (b > c)
; val = 1;
; b += c;
; }
;
; return val == 0 ? 1 : 0;
; }
define dso_local i32 @test(i64 %a, i64 %b, i64 %c) local_unnamed_addr {
entry:
br label %for.body
for.cond.cleanup: ; preds = %for.body
%cmp6 = icmp eq i32 %val.2, 0
%cond = zext i1 %cmp6 to i32
ret i32 %cond
for.body: ; preds = %for.body, %entry
%i.018 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
%val.017 = phi i32 [ 0, %entry ], [ %val.2, %for.body ]
%a.addr.016 = phi i64 [ %a, %entry ], [ %add, %for.body ]
%b.addr.015 = phi i64 [ %b, %entry ], [ %add5, %for.body ]
%cmp1 = icmp ugt i64 %a.addr.016, %b.addr.015
%add = add i64 %a.addr.016, %b.addr.015
%cmp2 = icmp ugt i64 %b.addr.015, %c
%0 = or i1 %cmp2, %cmp1
%val.2 = select i1 %0, i32 1, i32 %val.017
%add5 = add i64 %b.addr.015, %c
%inc = add nuw nsw i64 %i.018, 1
%exitcond = icmp eq i64 %inc, 100
br i1 %exitcond, label %for.cond.cleanup, label %for.body, !llvm.loop !2
}
; CHECK: [[VAL:r[0-9]+]] = w{{[0-9]+}}
; CHECK-NOT: [[VAL:r[0-9]+]] <<= 32
; CHECK-NOT: [[VAL]] >>= 32
; CHECK: if [[VAL]] == 0 goto
!2 = distinct !{!2, !3}
!3 = !{!"llvm.loop.unroll.disable"}