[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / ARM / CGP / arm-cgp-pointers.ll
blobe7f800232d45d0c739a9380685758b1002a5ddc0
1 ; RUN: llc -mtriple=thumbv8 -arm-disable-cgp=false %s -o - | FileCheck %s
2 ; RUN: llc -mtriple=armv8 -arm-disable-cgp=false %s -o - | FileCheck %s
4 ; CHECK-LABEL: phi_pointers
5 ; CHECK-NOT: uxt
6 define void @phi_pointers(i16* %a, i16* %b, i8 zeroext %M, i8 zeroext %N) {
7 entry:
8   %add = add nuw i8 %M, 1
9   %and = and i8 %add, 1
10   %cmp = icmp ugt i8 %add, %N
11   %base = select i1 %cmp, i16* %a, i16* %b
12   %other = select i1 %cmp, i16* %b, i16* %b
13   br label %loop
15 loop:
16   %ptr = phi i16* [ %base, %entry ], [ %gep, %loop ]
17   %idx = phi i8 [ %and, %entry ], [ %inc, %loop ]
18   %load = load i16, i16* %ptr, align 2
19   %inc = add nuw nsw i8 %idx, 1
20   %gep = getelementptr inbounds i16, i16* %ptr, i8 %inc
21   %cond = icmp eq i16* %gep, %other
22   br i1 %cond, label %exit, label %loop
24 exit:
25   ret void
28 ; CHECK-LABEL: phi_pointers_null
29 ; CHECK-NOT: uxt
30 define void @phi_pointers_null(i16* %a, i16* %b, i8 zeroext %M, i8 zeroext %N) {
31 entry:
32   %add = add nuw i8 %M, 1
33   %and = and i8 %add, 1
34   %cmp = icmp ugt i8 %add, %N
35   %base = select i1 %cmp, i16* %a, i16* %b
36   %other = select i1 %cmp, i16* %b, i16* %b
37   %cmp.1 = icmp eq i16* %base, %other
38   br i1 %cmp.1, label %fail, label %loop
40 fail:
41   br label %loop
43 loop:
44   %ptr = phi i16* [ %base, %entry ], [ null, %fail ], [ %gep, %if.then ]
45   %idx = phi i8 [ %and, %entry ], [ 0, %fail ], [ %inc, %if.then ]
46   %undef = icmp eq i16* %ptr, undef
47   br i1 %undef, label %exit, label %if.then
49 if.then:
50   %load = load i16, i16* %ptr, align 2
51   %inc = add nuw nsw i8 %idx, 1
52   %gep = getelementptr inbounds i16, i16* %ptr, i8 %inc
53   %cond = icmp eq i16* %gep, %other
54   br i1 %cond, label %exit, label %loop
56 exit:
57   ret void
60 declare i8 @do_something_with_ptr(i8, i16*)
62 ; CHECK-LABEL: call_pointer
63 ; CHECK-NOT: uxt
64 define i8 @call_pointer(i8 zeroext %x, i8 zeroext %y, i16* %a, i16* %b) {
65   %or = or i8 %x, %y
66   %shr = lshr i8 %or, 1
67   %add = add nuw i8 %shr, 2
68   %cmp = icmp ne i8 %add, 0
69   %ptr = select i1 %cmp, i16* %a, i16* %b
70   %call = tail call zeroext i8 @do_something_with_ptr(i8 %shr, i16* %ptr)
71   ret i8 %call
74 ; CHECK-LABEL: pointer_to_pointer
75 ; CHECK-NOT: uxt
76 define i16 @pointer_to_pointer(i16** %arg, i16 zeroext %limit) {
77 entry:
78   %addr = load i16*, i16** %arg
79   %val = load i16, i16* %addr
80   %add = add nuw i16 %val, 7
81   %cmp = icmp ult i16 %add, 256
82   %res = select i1 %cmp, i16 128, i16 255
83   ret i16 %res
86 ; CHECK-LABEL: gep_2d_array
87 ; CHECK-NOT: uxt
88 define i8 @gep_2d_array(i8** %a, i8 zeroext %arg) {
89 entry:
90   %arrayidx.us = getelementptr inbounds i8*, i8** %a, i32 0
91   %0 = load i8*, i8** %arrayidx.us, align 4
92   %1 = load i8, i8* %0, align 1
93   %sub = sub nuw i8 %1, 1
94   %cmp = icmp ult i8 %sub, %arg
95   %res = select i1 %cmp, i8 27, i8 54
96   ret i8 %res
99 ; CHECK-LABEL: gep_2d_array_loop
100 ; CHECK-NOT: uxt
101 define void @gep_2d_array_loop(i16** nocapture readonly %a, i16** nocapture readonly %b, i32 %N) {
102 entry:
103   %cmp30 = icmp eq i32 %N, 0
104   br i1 %cmp30, label %for.cond.cleanup, label %for.cond1.preheader.us
106 for.cond1.preheader.us:
107   %y.031.us = phi i32 [ %inc13.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ]
108   br label %for.body4.us
110 for.body4.us:
111   %x.029.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
112   %arrayidx.us = getelementptr inbounds i16*, i16** %a, i32 %x.029.us
113   %0 = load i16*, i16** %arrayidx.us, align 4
114   %arrayidx5.us = getelementptr inbounds i16, i16* %0, i32 %y.031.us
115   %1 = load i16, i16* %arrayidx5.us, align 2
116   %dec.us = add nuw i16 %1, -1
117   %cmp6.us = icmp ult i16 %dec.us, 16383
118   %shl.us = shl nuw i16 %dec.us, 2
119   %spec.select.us = select i1 %cmp6.us, i16 %shl.us, i16 %dec.us
120   %arrayidx10.us = getelementptr inbounds i16*, i16** %b, i32 %x.029.us
121   %2 = load i16*, i16** %arrayidx10.us, align 4
122   %arrayidx11.us = getelementptr inbounds i16, i16* %2, i32 %y.031.us
123   store i16 %spec.select.us, i16* %arrayidx11.us, align 2
124   %inc.us = add nuw i32 %x.029.us, 1
125   %exitcond = icmp eq i32 %inc.us, %N
126   br i1 %exitcond, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us
128 for.cond1.for.cond.cleanup3_crit_edge.us:
129   %inc13.us = add nuw i32 %y.031.us, 1
130   %exitcond32 = icmp eq i32 %inc13.us, %N
131   br i1 %exitcond32, label %for.cond.cleanup, label %for.cond1.preheader.us
133 for.cond.cleanup:
134   ret void