[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / LoopIdiom / AArch64 / byte-compare-index.ll
blob39037761c81bb3c4d51513e6ced6d0e6a7c2b341
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt -p loop-idiom-vectorize -loop-idiom-vectorize-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s
3 ; RUN: opt -passes='function(loop(loop-idiom-vectorize)),simplifycfg' -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=LOOP-DEL
4 ; RUN: opt -p loop-idiom-vectorize -mtriple aarch64-unknown-linux-gnu -S < %s | FileCheck %s --check-prefix=NO-TRANSFORM
6 define i32 @compare_bytes_simple(ptr %a, ptr %b, i32 %len, i32 %extra, i32 %n) {
7 ; CHECK-LABEL: define i32 @compare_bytes_simple(
8 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
11 ; CHECK-NEXT:    br label [[MISMATCH_MIN_IT_CHECK:%.*]]
12 ; CHECK:       mismatch_min_it_check:
13 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
14 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
15 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
16 ; CHECK-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0:![0-9]+]]
17 ; CHECK:       mismatch_mem_check:
18 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
19 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
20 ; CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
21 ; CHECK-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
22 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
23 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
24 ; CHECK-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
25 ; CHECK-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
26 ; CHECK-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
27 ; CHECK-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
28 ; CHECK-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
29 ; CHECK-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
30 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
31 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
32 ; CHECK-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
33 ; CHECK-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1:![0-9]+]]
34 ; CHECK:       mismatch_vec_loop_preheader:
35 ; CHECK-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
36 ; CHECK-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
37 ; CHECK-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
38 ; CHECK-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
39 ; CHECK:       mismatch_vec_loop:
40 ; CHECK-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
41 ; CHECK-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
42 ; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
43 ; CHECK-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
44 ; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
45 ; CHECK-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
46 ; CHECK-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
47 ; CHECK-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
48 ; CHECK-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
49 ; CHECK-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
50 ; CHECK:       mismatch_vec_loop_inc:
51 ; CHECK-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
52 ; CHECK-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
53 ; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
54 ; CHECK-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[MISMATCH_END:%.*]]
55 ; CHECK:       mismatch_vec_loop_found:
56 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
57 ; CHECK-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
58 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
59 ; CHECK-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
60 ; CHECK-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
61 ; CHECK-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
62 ; CHECK-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
63 ; CHECK-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
64 ; CHECK-NEXT:    br label [[MISMATCH_END]]
65 ; CHECK:       mismatch_loop_pre:
66 ; CHECK-NEXT:    br label [[MISMATCH_LOOP:%.*]]
67 ; CHECK:       mismatch_loop:
68 ; CHECK-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
69 ; CHECK-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
70 ; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
71 ; CHECK-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
72 ; CHECK-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
73 ; CHECK-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
74 ; CHECK-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
75 ; CHECK-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[MISMATCH_END]]
76 ; CHECK:       mismatch_loop_inc:
77 ; CHECK-NEXT:    [[TMP43]] = add i32 [[MISMATCH_INDEX]], 1
78 ; CHECK-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
79 ; CHECK-NEXT:    br i1 [[TMP44]], label [[MISMATCH_END]], label [[MISMATCH_LOOP]]
80 ; CHECK:       mismatch_end:
81 ; CHECK-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
82 ; CHECK-NEXT:    br i1 true, label [[BYTE_COMPARE:%.*]], label [[WHILE_COND:%.*]]
83 ; CHECK:       while.cond:
84 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[MISMATCH_END]] ], [ [[MISMATCH_RESULT]], [[WHILE_BODY:%.*]] ]
85 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LEN_ADDR]], 1
86 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], [[N]]
87 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
88 ; CHECK:       while.body:
89 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MISMATCH_RESULT]] to i64
90 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
91 ; CHECK-NEXT:    [[TMP45:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
92 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
93 ; CHECK-NEXT:    [[TMP46:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
94 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP45]], [[TMP46]]
95 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
96 ; CHECK:       byte.compare:
97 ; CHECK-NEXT:    br label [[WHILE_END]]
98 ; CHECK:       while.end:
99 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[MISMATCH_RESULT]], [[WHILE_BODY]] ], [ [[MISMATCH_RESULT]], [[WHILE_COND]] ], [ [[MISMATCH_RESULT]], [[BYTE_COMPARE]] ]
100 ; CHECK-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ], [ [[EXTRA]], [[BYTE_COMPARE]] ]
101 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
102 ; CHECK-NEXT:    ret i32 [[RES]]
104 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple(
105 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
106 ; LOOP-DEL-NEXT:  entry:
107 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
108 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
109 ; LOOP-DEL-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
110 ; LOOP-DEL-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
111 ; LOOP-DEL-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0:![0-9]+]]
112 ; LOOP-DEL:       mismatch_mem_check:
113 ; LOOP-DEL-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
114 ; LOOP-DEL-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
115 ; LOOP-DEL-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
116 ; LOOP-DEL-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
117 ; LOOP-DEL-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
118 ; LOOP-DEL-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
119 ; LOOP-DEL-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
120 ; LOOP-DEL-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
121 ; LOOP-DEL-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
122 ; LOOP-DEL-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
123 ; LOOP-DEL-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
124 ; LOOP-DEL-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
125 ; LOOP-DEL-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
126 ; LOOP-DEL-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
127 ; LOOP-DEL-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
128 ; LOOP-DEL-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1:![0-9]+]]
129 ; LOOP-DEL:       mismatch_vec_loop_preheader:
130 ; LOOP-DEL-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
131 ; LOOP-DEL-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
132 ; LOOP-DEL-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
133 ; LOOP-DEL-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
134 ; LOOP-DEL:       mismatch_vec_loop:
135 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
136 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
137 ; LOOP-DEL-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
138 ; LOOP-DEL-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
139 ; LOOP-DEL-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
140 ; LOOP-DEL-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
141 ; LOOP-DEL-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
142 ; LOOP-DEL-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
143 ; LOOP-DEL-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
144 ; LOOP-DEL-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
145 ; LOOP-DEL:       mismatch_vec_loop_inc:
146 ; LOOP-DEL-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
147 ; LOOP-DEL-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
148 ; LOOP-DEL-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
149 ; LOOP-DEL-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[WHILE_END:%.*]]
150 ; LOOP-DEL:       mismatch_vec_loop_found:
151 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
152 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
153 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
154 ; LOOP-DEL-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
155 ; LOOP-DEL-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
156 ; LOOP-DEL-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
157 ; LOOP-DEL-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
158 ; LOOP-DEL-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
159 ; LOOP-DEL-NEXT:    br label [[WHILE_END]]
160 ; LOOP-DEL:       mismatch_loop_pre:
161 ; LOOP-DEL-NEXT:    br label [[MISMATCH_LOOP:%.*]]
162 ; LOOP-DEL:       mismatch_loop:
163 ; LOOP-DEL-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
164 ; LOOP-DEL-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
165 ; LOOP-DEL-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
166 ; LOOP-DEL-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
167 ; LOOP-DEL-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
168 ; LOOP-DEL-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
169 ; LOOP-DEL-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
170 ; LOOP-DEL-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[WHILE_END]]
171 ; LOOP-DEL:       mismatch_loop_inc:
172 ; LOOP-DEL-NEXT:    [[TMP43]] = add i32 [[MISMATCH_INDEX]], 1
173 ; LOOP-DEL-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
174 ; LOOP-DEL-NEXT:    br i1 [[TMP44]], label [[WHILE_END]], label [[MISMATCH_LOOP]]
175 ; LOOP-DEL:       while.end:
176 ; LOOP-DEL-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
177 ; LOOP-DEL-NEXT:    [[RES:%.*]] = add i32 [[MISMATCH_RESULT]], [[EXTRA]]
178 ; LOOP-DEL-NEXT:    ret i32 [[RES]]
180 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple(
181 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) {
182 ; NO-TRANSFORM-NEXT:  entry:
183 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
184 ; NO-TRANSFORM:       while.cond:
185 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
186 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
187 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
188 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
189 ; NO-TRANSFORM:       while.body:
190 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
191 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
192 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
193 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
194 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
195 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
196 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
197 ; NO-TRANSFORM:       while.end:
198 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
199 ; NO-TRANSFORM-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
200 ; NO-TRANSFORM-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
201 ; NO-TRANSFORM-NEXT:    ret i32 [[RES]]
203 entry:
204   br label %while.cond
206 while.cond:
207   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
208   %inc = add i32 %len.addr, 1
209   %cmp.not = icmp eq i32 %inc, %n
210   br i1 %cmp.not, label %while.end, label %while.body
212 while.body:
213   %idxprom = zext i32 %inc to i64
214   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
215   %0 = load i8, ptr %arrayidx
216   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
217   %1 = load i8, ptr %arrayidx2
218   %cmp.not2 = icmp eq i8 %0, %1
219   br i1 %cmp.not2, label %while.cond, label %while.end
221 while.end:
222   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
223   %extra.phi = phi i32 [ %extra, %while.body ], [ %extra, %while.cond ]
224   %res = add i32 %inc.lcssa, %extra.phi
225   ret i32 %res
229 define i32 @compare_bytes_signed_wrap(ptr %a, ptr %b, i32 %len, i32 %n) {
230 ; CHECK-LABEL: define i32 @compare_bytes_signed_wrap(
231 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
232 ; CHECK-NEXT:  entry:
233 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
234 ; CHECK-NEXT:    br label [[MISMATCH_MIN_IT_CHECK:%.*]]
235 ; CHECK:       mismatch_min_it_check:
236 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
237 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
238 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
239 ; CHECK-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
240 ; CHECK:       mismatch_mem_check:
241 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
242 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
243 ; CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
244 ; CHECK-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
245 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
246 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
247 ; CHECK-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
248 ; CHECK-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
249 ; CHECK-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
250 ; CHECK-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
251 ; CHECK-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
252 ; CHECK-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
253 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
254 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
255 ; CHECK-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
256 ; CHECK-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
257 ; CHECK:       mismatch_vec_loop_preheader:
258 ; CHECK-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
259 ; CHECK-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
260 ; CHECK-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
261 ; CHECK-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
262 ; CHECK:       mismatch_vec_loop:
263 ; CHECK-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
264 ; CHECK-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
265 ; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
266 ; CHECK-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
267 ; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
268 ; CHECK-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
269 ; CHECK-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
270 ; CHECK-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
271 ; CHECK-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
272 ; CHECK-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
273 ; CHECK:       mismatch_vec_loop_inc:
274 ; CHECK-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
275 ; CHECK-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
276 ; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
277 ; CHECK-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[MISMATCH_END:%.*]]
278 ; CHECK:       mismatch_vec_loop_found:
279 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
280 ; CHECK-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
281 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
282 ; CHECK-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
283 ; CHECK-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
284 ; CHECK-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
285 ; CHECK-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
286 ; CHECK-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
287 ; CHECK-NEXT:    br label [[MISMATCH_END]]
288 ; CHECK:       mismatch_loop_pre:
289 ; CHECK-NEXT:    br label [[MISMATCH_LOOP:%.*]]
290 ; CHECK:       mismatch_loop:
291 ; CHECK-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
292 ; CHECK-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
293 ; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
294 ; CHECK-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
295 ; CHECK-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
296 ; CHECK-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
297 ; CHECK-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
298 ; CHECK-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[MISMATCH_END]]
299 ; CHECK:       mismatch_loop_inc:
300 ; CHECK-NEXT:    [[TMP43]] = add nsw i32 [[MISMATCH_INDEX]], 1
301 ; CHECK-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
302 ; CHECK-NEXT:    br i1 [[TMP44]], label [[MISMATCH_END]], label [[MISMATCH_LOOP]]
303 ; CHECK:       mismatch_end:
304 ; CHECK-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
305 ; CHECK-NEXT:    br i1 true, label [[BYTE_COMPARE:%.*]], label [[WHILE_COND:%.*]]
306 ; CHECK:       while.cond:
307 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[MISMATCH_END]] ], [ [[MISMATCH_RESULT]], [[WHILE_BODY:%.*]] ]
308 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[LEN_ADDR]], 1
309 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], [[N]]
310 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
311 ; CHECK:       while.body:
312 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MISMATCH_RESULT]] to i64
313 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
314 ; CHECK-NEXT:    [[TMP45:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
315 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
316 ; CHECK-NEXT:    [[TMP46:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
317 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP45]], [[TMP46]]
318 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
319 ; CHECK:       byte.compare:
320 ; CHECK-NEXT:    br label [[WHILE_END]]
321 ; CHECK:       while.end:
322 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[MISMATCH_RESULT]], [[WHILE_BODY]] ], [ [[MISMATCH_RESULT]], [[WHILE_COND]] ], [ [[MISMATCH_RESULT]], [[BYTE_COMPARE]] ]
323 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
325 ; LOOP-DEL-LABEL: define i32 @compare_bytes_signed_wrap(
326 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
327 ; LOOP-DEL-NEXT:  entry:
328 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
329 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
330 ; LOOP-DEL-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
331 ; LOOP-DEL-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
332 ; LOOP-DEL-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
333 ; LOOP-DEL:       mismatch_mem_check:
334 ; LOOP-DEL-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
335 ; LOOP-DEL-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
336 ; LOOP-DEL-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
337 ; LOOP-DEL-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
338 ; LOOP-DEL-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
339 ; LOOP-DEL-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
340 ; LOOP-DEL-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
341 ; LOOP-DEL-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
342 ; LOOP-DEL-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
343 ; LOOP-DEL-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
344 ; LOOP-DEL-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
345 ; LOOP-DEL-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
346 ; LOOP-DEL-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
347 ; LOOP-DEL-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
348 ; LOOP-DEL-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
349 ; LOOP-DEL-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
350 ; LOOP-DEL:       mismatch_vec_loop_preheader:
351 ; LOOP-DEL-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
352 ; LOOP-DEL-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
353 ; LOOP-DEL-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
354 ; LOOP-DEL-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
355 ; LOOP-DEL:       mismatch_vec_loop:
356 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
357 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
358 ; LOOP-DEL-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
359 ; LOOP-DEL-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
360 ; LOOP-DEL-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
361 ; LOOP-DEL-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
362 ; LOOP-DEL-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
363 ; LOOP-DEL-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
364 ; LOOP-DEL-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
365 ; LOOP-DEL-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
366 ; LOOP-DEL:       mismatch_vec_loop_inc:
367 ; LOOP-DEL-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
368 ; LOOP-DEL-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
369 ; LOOP-DEL-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
370 ; LOOP-DEL-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[WHILE_END:%.*]]
371 ; LOOP-DEL:       mismatch_vec_loop_found:
372 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
373 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
374 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
375 ; LOOP-DEL-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
376 ; LOOP-DEL-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
377 ; LOOP-DEL-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
378 ; LOOP-DEL-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
379 ; LOOP-DEL-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
380 ; LOOP-DEL-NEXT:    br label [[WHILE_END]]
381 ; LOOP-DEL:       mismatch_loop_pre:
382 ; LOOP-DEL-NEXT:    br label [[MISMATCH_LOOP:%.*]]
383 ; LOOP-DEL:       mismatch_loop:
384 ; LOOP-DEL-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
385 ; LOOP-DEL-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
386 ; LOOP-DEL-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
387 ; LOOP-DEL-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
388 ; LOOP-DEL-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
389 ; LOOP-DEL-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
390 ; LOOP-DEL-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
391 ; LOOP-DEL-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[WHILE_END]]
392 ; LOOP-DEL:       mismatch_loop_inc:
393 ; LOOP-DEL-NEXT:    [[TMP43]] = add nsw i32 [[MISMATCH_INDEX]], 1
394 ; LOOP-DEL-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
395 ; LOOP-DEL-NEXT:    br i1 [[TMP44]], label [[WHILE_END]], label [[MISMATCH_LOOP]]
396 ; LOOP-DEL:       while.end:
397 ; LOOP-DEL-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
398 ; LOOP-DEL-NEXT:    ret i32 [[MISMATCH_RESULT]]
400 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_signed_wrap(
401 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
402 ; NO-TRANSFORM-NEXT:  entry:
403 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
404 ; NO-TRANSFORM:       while.cond:
405 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
406 ; NO-TRANSFORM-NEXT:    [[INC]] = add nsw i32 [[LEN_ADDR]], 1
407 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
408 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
409 ; NO-TRANSFORM:       while.body:
410 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
411 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
412 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
413 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
414 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
415 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
416 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
417 ; NO-TRANSFORM:       while.end:
418 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
419 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
421 entry:
422   br label %while.cond
424 while.cond:
425   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
426   %inc = add nsw i32 %len.addr, 1
427   %cmp.not = icmp eq i32 %inc, %n
428   br i1 %cmp.not, label %while.end, label %while.body
430 while.body:
431   %idxprom = zext i32 %inc to i64
432   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
433   %0 = load i8, ptr %arrayidx
434   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
435   %1 = load i8, ptr %arrayidx2
436   %cmp.not2 = icmp eq i8 %0, %1
437   br i1 %cmp.not2, label %while.cond, label %while.end
439 while.end:
440   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
441   ret i32 %inc.lcssa
445 define i32 @compare_bytes_simple_end_ne_found(ptr %a, ptr %b, ptr %c, ptr %d, i32 %len, i32 %n) {
446 ; CHECK-LABEL: define i32 @compare_bytes_simple_end_ne_found(
447 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
448 ; CHECK-NEXT:  entry:
449 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
450 ; CHECK-NEXT:    br label [[MISMATCH_MIN_IT_CHECK:%.*]]
451 ; CHECK:       mismatch_min_it_check:
452 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
453 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
454 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
455 ; CHECK-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
456 ; CHECK:       mismatch_mem_check:
457 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
458 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
459 ; CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
460 ; CHECK-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
461 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
462 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
463 ; CHECK-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
464 ; CHECK-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
465 ; CHECK-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
466 ; CHECK-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
467 ; CHECK-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
468 ; CHECK-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
469 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
470 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
471 ; CHECK-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
472 ; CHECK-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
473 ; CHECK:       mismatch_vec_loop_preheader:
474 ; CHECK-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
475 ; CHECK-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
476 ; CHECK-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
477 ; CHECK-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
478 ; CHECK:       mismatch_vec_loop:
479 ; CHECK-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
480 ; CHECK-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
481 ; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
482 ; CHECK-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
483 ; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
484 ; CHECK-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
485 ; CHECK-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
486 ; CHECK-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
487 ; CHECK-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
488 ; CHECK-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
489 ; CHECK:       mismatch_vec_loop_inc:
490 ; CHECK-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
491 ; CHECK-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
492 ; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
493 ; CHECK-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[MISMATCH_END:%.*]]
494 ; CHECK:       mismatch_vec_loop_found:
495 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
496 ; CHECK-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
497 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
498 ; CHECK-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
499 ; CHECK-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
500 ; CHECK-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
501 ; CHECK-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
502 ; CHECK-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
503 ; CHECK-NEXT:    br label [[MISMATCH_END]]
504 ; CHECK:       mismatch_loop_pre:
505 ; CHECK-NEXT:    br label [[MISMATCH_LOOP:%.*]]
506 ; CHECK:       mismatch_loop:
507 ; CHECK-NEXT:    [[MISMATCH_INDEX3:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
508 ; CHECK-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX3]] to i64
509 ; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
510 ; CHECK-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
511 ; CHECK-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
512 ; CHECK-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
513 ; CHECK-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
514 ; CHECK-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[MISMATCH_END]]
515 ; CHECK:       mismatch_loop_inc:
516 ; CHECK-NEXT:    [[TMP43]] = add i32 [[MISMATCH_INDEX3]], 1
517 ; CHECK-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
518 ; CHECK-NEXT:    br i1 [[TMP44]], label [[MISMATCH_END]], label [[MISMATCH_LOOP]]
519 ; CHECK:       mismatch_end:
520 ; CHECK-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX3]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
521 ; CHECK-NEXT:    br i1 true, label [[BYTE_COMPARE:%.*]], label [[WHILE_COND:%.*]]
522 ; CHECK:       while.cond:
523 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[MISMATCH_END]] ], [ [[MISMATCH_RESULT]], [[WHILE_BODY:%.*]] ]
524 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LEN_ADDR]], 1
525 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], [[N]]
526 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
527 ; CHECK:       while.body:
528 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MISMATCH_RESULT]] to i64
529 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
530 ; CHECK-NEXT:    [[TMP45:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
531 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
532 ; CHECK-NEXT:    [[TMP46:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
533 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP45]], [[TMP46]]
534 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_FOUND:%.*]]
535 ; CHECK:       while.found:
536 ; CHECK-NEXT:    [[MISMATCH_INDEX1:%.*]] = phi i32 [ [[MISMATCH_RESULT]], [[WHILE_BODY]] ], [ [[MISMATCH_RESULT]], [[BYTE_COMPARE]] ]
537 ; CHECK-NEXT:    [[FOUND_PTR:%.*]] = phi ptr [ [[C]], [[WHILE_BODY]] ], [ [[C]], [[BYTE_COMPARE]] ]
538 ; CHECK-NEXT:    br label [[END:%.*]]
539 ; CHECK:       byte.compare:
540 ; CHECK-NEXT:    [[TMP47:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], [[N]]
541 ; CHECK-NEXT:    br i1 [[TMP47]], label [[WHILE_END]], label [[WHILE_FOUND]]
542 ; CHECK:       while.end:
543 ; CHECK-NEXT:    [[MISMATCH_INDEX2:%.*]] = phi i32 [ [[N]], [[WHILE_COND]] ], [ [[N]], [[BYTE_COMPARE]] ]
544 ; CHECK-NEXT:    [[END_PTR:%.*]] = phi ptr [ [[D]], [[WHILE_COND]] ], [ [[D]], [[BYTE_COMPARE]] ]
545 ; CHECK-NEXT:    br label [[END]]
546 ; CHECK:       end:
547 ; CHECK-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[MISMATCH_INDEX1]], [[WHILE_FOUND]] ], [ [[MISMATCH_INDEX2]], [[WHILE_END]] ]
548 ; CHECK-NEXT:    [[STORE_PTR:%.*]] = phi ptr [ [[END_PTR]], [[WHILE_END]] ], [ [[FOUND_PTR]], [[WHILE_FOUND]] ]
549 ; CHECK-NEXT:    store i32 [[MISMATCH_INDEX]], ptr [[STORE_PTR]], align 4
550 ; CHECK-NEXT:    ret i32 [[MISMATCH_INDEX]]
552 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple_end_ne_found(
553 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
554 ; LOOP-DEL-NEXT:  entry:
555 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
556 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
557 ; LOOP-DEL-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
558 ; LOOP-DEL-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
559 ; LOOP-DEL-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
560 ; LOOP-DEL:       mismatch_mem_check:
561 ; LOOP-DEL-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
562 ; LOOP-DEL-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
563 ; LOOP-DEL-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
564 ; LOOP-DEL-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
565 ; LOOP-DEL-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
566 ; LOOP-DEL-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
567 ; LOOP-DEL-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
568 ; LOOP-DEL-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
569 ; LOOP-DEL-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
570 ; LOOP-DEL-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
571 ; LOOP-DEL-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
572 ; LOOP-DEL-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
573 ; LOOP-DEL-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
574 ; LOOP-DEL-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
575 ; LOOP-DEL-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
576 ; LOOP-DEL-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
577 ; LOOP-DEL:       mismatch_vec_loop_preheader:
578 ; LOOP-DEL-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
579 ; LOOP-DEL-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
580 ; LOOP-DEL-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
581 ; LOOP-DEL-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
582 ; LOOP-DEL:       mismatch_vec_loop:
583 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
584 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
585 ; LOOP-DEL-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
586 ; LOOP-DEL-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
587 ; LOOP-DEL-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
588 ; LOOP-DEL-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
589 ; LOOP-DEL-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
590 ; LOOP-DEL-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
591 ; LOOP-DEL-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
592 ; LOOP-DEL-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
593 ; LOOP-DEL:       mismatch_vec_loop_inc:
594 ; LOOP-DEL-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
595 ; LOOP-DEL-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
596 ; LOOP-DEL-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
597 ; LOOP-DEL-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[BYTE_COMPARE:%.*]]
598 ; LOOP-DEL:       mismatch_vec_loop_found:
599 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
600 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
601 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
602 ; LOOP-DEL-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
603 ; LOOP-DEL-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
604 ; LOOP-DEL-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
605 ; LOOP-DEL-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
606 ; LOOP-DEL-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
607 ; LOOP-DEL-NEXT:    br label [[BYTE_COMPARE]]
608 ; LOOP-DEL:       mismatch_loop_pre:
609 ; LOOP-DEL-NEXT:    br label [[MISMATCH_LOOP:%.*]]
610 ; LOOP-DEL:       mismatch_loop:
611 ; LOOP-DEL-NEXT:    [[MISMATCH_INDEX3:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
612 ; LOOP-DEL-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX3]] to i64
613 ; LOOP-DEL-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
614 ; LOOP-DEL-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
615 ; LOOP-DEL-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
616 ; LOOP-DEL-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
617 ; LOOP-DEL-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
618 ; LOOP-DEL-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[BYTE_COMPARE]]
619 ; LOOP-DEL:       mismatch_loop_inc:
620 ; LOOP-DEL-NEXT:    [[TMP43]] = add i32 [[MISMATCH_INDEX3]], 1
621 ; LOOP-DEL-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
622 ; LOOP-DEL-NEXT:    br i1 [[TMP44]], label [[BYTE_COMPARE]], label [[MISMATCH_LOOP]]
623 ; LOOP-DEL:       byte.compare:
624 ; LOOP-DEL-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX3]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
625 ; LOOP-DEL-NEXT:    [[TMP45:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], [[N]]
626 ; LOOP-DEL-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TMP45]], i32 [[N]], i32 [[MISMATCH_RESULT]]
627 ; LOOP-DEL-NEXT:    [[SPEC_SELECT4:%.*]] = select i1 [[TMP45]], ptr [[D]], ptr [[C]]
628 ; LOOP-DEL-NEXT:    store i32 [[SPEC_SELECT]], ptr [[SPEC_SELECT4]], align 4
629 ; LOOP-DEL-NEXT:    ret i32 [[SPEC_SELECT]]
631 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple_end_ne_found(
632 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
633 ; NO-TRANSFORM-NEXT:  entry:
634 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
635 ; NO-TRANSFORM:       while.cond:
636 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
637 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
638 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
639 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
640 ; NO-TRANSFORM:       while.body:
641 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
642 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
643 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
644 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
645 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
646 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
647 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_FOUND:%.*]]
648 ; NO-TRANSFORM:       while.found:
649 ; NO-TRANSFORM-NEXT:    [[MISMATCH_INDEX1:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
650 ; NO-TRANSFORM-NEXT:    [[FOUND_PTR:%.*]] = phi ptr [ [[C]], [[WHILE_BODY]] ]
651 ; NO-TRANSFORM-NEXT:    br label [[END:%.*]]
652 ; NO-TRANSFORM:       while.end:
653 ; NO-TRANSFORM-NEXT:    [[MISMATCH_INDEX2:%.*]] = phi i32 [ [[N]], [[WHILE_COND]] ]
654 ; NO-TRANSFORM-NEXT:    [[END_PTR:%.*]] = phi ptr [ [[D]], [[WHILE_COND]] ]
655 ; NO-TRANSFORM-NEXT:    br label [[END]]
656 ; NO-TRANSFORM:       end:
657 ; NO-TRANSFORM-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[MISMATCH_INDEX1]], [[WHILE_FOUND]] ], [ [[MISMATCH_INDEX2]], [[WHILE_END]] ]
658 ; NO-TRANSFORM-NEXT:    [[STORE_PTR:%.*]] = phi ptr [ [[END_PTR]], [[WHILE_END]] ], [ [[FOUND_PTR]], [[WHILE_FOUND]] ]
659 ; NO-TRANSFORM-NEXT:    store i32 [[MISMATCH_INDEX]], ptr [[STORE_PTR]], align 4
660 ; NO-TRANSFORM-NEXT:    ret i32 [[MISMATCH_INDEX]]
662 entry:
663   br label %while.cond
665 while.cond:
666   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
667   %inc = add i32 %len.addr, 1
668   %cmp.not = icmp eq i32 %inc, %n
669   br i1 %cmp.not, label %while.end, label %while.body
671 while.body:
672   %idxprom = zext i32 %inc to i64
673   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
674   %0 = load i8, ptr %arrayidx
675   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
676   %1 = load i8, ptr %arrayidx2
677   %cmp.not2 = icmp eq i8 %0, %1
678   br i1 %cmp.not2, label %while.cond, label %while.found
680 while.found:
681   %mismatch_index1 = phi i32 [ %inc, %while.body ]
682   %found_ptr = phi ptr [ %c, %while.body ]
683   br label %end
685 while.end:
686   %mismatch_index2 = phi i32 [ %n, %while.cond ]
687   %end_ptr = phi ptr [ %d, %while.cond ]
688   br label %end
690 end:
691   %mismatch_index = phi i32 [ %mismatch_index1, %while.found ], [ %mismatch_index2, %while.end ]
692   %store_ptr = phi ptr [ %end_ptr, %while.end ], [ %found_ptr, %while.found ]
693   store i32 %mismatch_index, ptr %store_ptr
694   ret i32 %mismatch_index
699 define i32 @compare_bytes_extra_cmp(ptr %a, ptr %b, i32 %len, i32 %n, i32 %x) {
700 ; CHECK-LABEL: define i32 @compare_bytes_extra_cmp(
701 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
702 ; CHECK-NEXT:  entry:
703 ; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ult i32 [[N]], [[X]]
704 ; CHECK-NEXT:    br i1 [[CMP_X]], label [[PH:%.*]], label [[WHILE_END:%.*]]
705 ; CHECK:       ph:
706 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
707 ; CHECK-NEXT:    br label [[MISMATCH_MIN_IT_CHECK:%.*]]
708 ; CHECK:       mismatch_min_it_check:
709 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
710 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
711 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
712 ; CHECK-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
713 ; CHECK:       mismatch_mem_check:
714 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
715 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
716 ; CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
717 ; CHECK-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
718 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
719 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
720 ; CHECK-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
721 ; CHECK-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
722 ; CHECK-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
723 ; CHECK-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
724 ; CHECK-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
725 ; CHECK-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
726 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
727 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
728 ; CHECK-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
729 ; CHECK-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
730 ; CHECK:       mismatch_vec_loop_preheader:
731 ; CHECK-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
732 ; CHECK-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
733 ; CHECK-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
734 ; CHECK-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
735 ; CHECK:       mismatch_vec_loop:
736 ; CHECK-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
737 ; CHECK-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
738 ; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
739 ; CHECK-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
740 ; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
741 ; CHECK-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
742 ; CHECK-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
743 ; CHECK-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
744 ; CHECK-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
745 ; CHECK-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
746 ; CHECK:       mismatch_vec_loop_inc:
747 ; CHECK-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
748 ; CHECK-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
749 ; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
750 ; CHECK-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[MISMATCH_END:%.*]]
751 ; CHECK:       mismatch_vec_loop_found:
752 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
753 ; CHECK-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
754 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
755 ; CHECK-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
756 ; CHECK-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
757 ; CHECK-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
758 ; CHECK-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
759 ; CHECK-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
760 ; CHECK-NEXT:    br label [[MISMATCH_END]]
761 ; CHECK:       mismatch_loop_pre:
762 ; CHECK-NEXT:    br label [[MISMATCH_LOOP:%.*]]
763 ; CHECK:       mismatch_loop:
764 ; CHECK-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
765 ; CHECK-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
766 ; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
767 ; CHECK-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
768 ; CHECK-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
769 ; CHECK-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
770 ; CHECK-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
771 ; CHECK-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[MISMATCH_END]]
772 ; CHECK:       mismatch_loop_inc:
773 ; CHECK-NEXT:    [[TMP43]] = add i32 [[MISMATCH_INDEX]], 1
774 ; CHECK-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
775 ; CHECK-NEXT:    br i1 [[TMP44]], label [[MISMATCH_END]], label [[MISMATCH_LOOP]]
776 ; CHECK:       mismatch_end:
777 ; CHECK-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
778 ; CHECK-NEXT:    br i1 true, label [[BYTE_COMPARE:%.*]], label [[WHILE_COND:%.*]]
779 ; CHECK:       while.cond:
780 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[MISMATCH_END]] ], [ [[MISMATCH_RESULT]], [[WHILE_BODY:%.*]] ]
781 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LEN_ADDR]], 1
782 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], [[N]]
783 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
784 ; CHECK:       while.body:
785 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MISMATCH_RESULT]] to i64
786 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
787 ; CHECK-NEXT:    [[TMP45:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
788 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
789 ; CHECK-NEXT:    [[TMP46:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
790 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP45]], [[TMP46]]
791 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END_LOOPEXIT]]
792 ; CHECK:       byte.compare:
793 ; CHECK-NEXT:    br label [[WHILE_END_LOOPEXIT]]
794 ; CHECK:       while.end.loopexit:
795 ; CHECK-NEXT:    [[INC_LCSSA1:%.*]] = phi i32 [ [[MISMATCH_RESULT]], [[WHILE_COND]] ], [ [[MISMATCH_RESULT]], [[WHILE_BODY]] ], [ [[MISMATCH_RESULT]], [[BYTE_COMPARE]] ]
796 ; CHECK-NEXT:    br label [[WHILE_END]]
797 ; CHECK:       while.end:
798 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[X]], [[ENTRY:%.*]] ], [ [[INC_LCSSA1]], [[WHILE_END_LOOPEXIT]] ]
799 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
801 ; LOOP-DEL-LABEL: define i32 @compare_bytes_extra_cmp(
802 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
803 ; LOOP-DEL-NEXT:  entry:
804 ; LOOP-DEL-NEXT:    [[CMP_X:%.*]] = icmp ult i32 [[N]], [[X]]
805 ; LOOP-DEL-NEXT:    br i1 [[CMP_X]], label [[PH:%.*]], label [[WHILE_END:%.*]]
806 ; LOOP-DEL:       ph:
807 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = add i32 [[LEN]], 1
808 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
809 ; LOOP-DEL-NEXT:    [[TMP2:%.*]] = zext i32 [[N]] to i64
810 ; LOOP-DEL-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[TMP0]], [[N]]
811 ; LOOP-DEL-NEXT:    br i1 [[TMP3]], label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
812 ; LOOP-DEL:       mismatch_mem_check:
813 ; LOOP-DEL-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]
814 ; LOOP-DEL-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP1]]
815 ; LOOP-DEL-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64
816 ; LOOP-DEL-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64
817 ; LOOP-DEL-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]
818 ; LOOP-DEL-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP2]]
819 ; LOOP-DEL-NEXT:    [[TMP10:%.*]] = ptrtoint ptr [[TMP8]] to i64
820 ; LOOP-DEL-NEXT:    [[TMP11:%.*]] = ptrtoint ptr [[TMP9]] to i64
821 ; LOOP-DEL-NEXT:    [[TMP12:%.*]] = lshr i64 [[TMP7]], 12
822 ; LOOP-DEL-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP10]], 12
823 ; LOOP-DEL-NEXT:    [[TMP14:%.*]] = lshr i64 [[TMP6]], 12
824 ; LOOP-DEL-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 12
825 ; LOOP-DEL-NEXT:    [[TMP16:%.*]] = icmp ne i64 [[TMP12]], [[TMP13]]
826 ; LOOP-DEL-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP14]], [[TMP15]]
827 ; LOOP-DEL-NEXT:    [[TMP18:%.*]] = or i1 [[TMP16]], [[TMP17]]
828 ; LOOP-DEL-NEXT:    br i1 [[TMP18]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
829 ; LOOP-DEL:       mismatch_vec_loop_preheader:
830 ; LOOP-DEL-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP1]], i64 [[TMP2]])
831 ; LOOP-DEL-NEXT:    [[TMP20:%.*]] = call i64 @llvm.vscale.i64()
832 ; LOOP-DEL-NEXT:    [[TMP21:%.*]] = mul nuw nsw i64 [[TMP20]], 16
833 ; LOOP-DEL-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
834 ; LOOP-DEL:       mismatch_vec_loop:
835 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP19]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP30:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
836 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ [[TMP1]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP29:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
837 ; LOOP-DEL-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[MISMATCH_VEC_INDEX]]
838 ; LOOP-DEL-NEXT:    [[TMP23:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP22]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
839 ; LOOP-DEL-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[MISMATCH_VEC_INDEX]]
840 ; LOOP-DEL-NEXT:    [[TMP25:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP24]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
841 ; LOOP-DEL-NEXT:    [[TMP26:%.*]] = icmp ne <vscale x 16 x i8> [[TMP23]], [[TMP25]]
842 ; LOOP-DEL-NEXT:    [[TMP27:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP26]], <vscale x 16 x i1> zeroinitializer
843 ; LOOP-DEL-NEXT:    [[TMP28:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP27]])
844 ; LOOP-DEL-NEXT:    br i1 [[TMP28]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
845 ; LOOP-DEL:       mismatch_vec_loop_inc:
846 ; LOOP-DEL-NEXT:    [[TMP29]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP21]]
847 ; LOOP-DEL-NEXT:    [[TMP30]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP29]], i64 [[TMP2]])
848 ; LOOP-DEL-NEXT:    [[TMP31:%.*]] = extractelement <vscale x 16 x i1> [[TMP30]], i64 0
849 ; LOOP-DEL-NEXT:    br i1 [[TMP31]], label [[MISMATCH_VEC_LOOP]], label [[WHILE_END]]
850 ; LOOP-DEL:       mismatch_vec_loop_found:
851 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP27]], [[MISMATCH_VEC_LOOP]] ]
852 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
853 ; LOOP-DEL-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
854 ; LOOP-DEL-NEXT:    [[TMP32:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
855 ; LOOP-DEL-NEXT:    [[TMP33:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP32]], i1 true)
856 ; LOOP-DEL-NEXT:    [[TMP34:%.*]] = zext i32 [[TMP33]] to i64
857 ; LOOP-DEL-NEXT:    [[TMP35:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP34]]
858 ; LOOP-DEL-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
859 ; LOOP-DEL-NEXT:    br label [[WHILE_END]]
860 ; LOOP-DEL:       mismatch_loop_pre:
861 ; LOOP-DEL-NEXT:    br label [[MISMATCH_LOOP:%.*]]
862 ; LOOP-DEL:       mismatch_loop:
863 ; LOOP-DEL-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ [[TMP0]], [[MISMATCH_LOOP_PRE]] ], [ [[TMP43:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
864 ; LOOP-DEL-NEXT:    [[TMP37:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
865 ; LOOP-DEL-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[TMP37]]
866 ; LOOP-DEL-NEXT:    [[TMP39:%.*]] = load i8, ptr [[TMP38]], align 1
867 ; LOOP-DEL-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[TMP37]]
868 ; LOOP-DEL-NEXT:    [[TMP41:%.*]] = load i8, ptr [[TMP40]], align 1
869 ; LOOP-DEL-NEXT:    [[TMP42:%.*]] = icmp eq i8 [[TMP39]], [[TMP41]]
870 ; LOOP-DEL-NEXT:    br i1 [[TMP42]], label [[MISMATCH_LOOP_INC]], label [[WHILE_END]]
871 ; LOOP-DEL:       mismatch_loop_inc:
872 ; LOOP-DEL-NEXT:    [[TMP43]] = add i32 [[MISMATCH_INDEX]], 1
873 ; LOOP-DEL-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], [[N]]
874 ; LOOP-DEL-NEXT:    br i1 [[TMP44]], label [[WHILE_END]], label [[MISMATCH_LOOP]]
875 ; LOOP-DEL:       while.end:
876 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[X]], [[ENTRY:%.*]] ], [ [[N]], [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ [[N]], [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP36]], [[MISMATCH_VEC_LOOP_FOUND]] ]
877 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
879 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_extra_cmp(
880 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]], i32 [[X:%.*]]) {
881 ; NO-TRANSFORM-NEXT:  entry:
882 ; NO-TRANSFORM-NEXT:    [[CMP_X:%.*]] = icmp ult i32 [[N]], [[X]]
883 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_X]], label [[PH:%.*]], label [[WHILE_END:%.*]]
884 ; NO-TRANSFORM:       ph:
885 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
886 ; NO-TRANSFORM:       while.cond:
887 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[PH]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
888 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
889 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
890 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
891 ; NO-TRANSFORM:       while.body:
892 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
893 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
894 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
895 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
896 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
897 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
898 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END_LOOPEXIT]]
899 ; NO-TRANSFORM:       while.end.loopexit:
900 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA1:%.*]] = phi i32 [ [[INC]], [[WHILE_COND]] ], [ [[INC]], [[WHILE_BODY]] ]
901 ; NO-TRANSFORM-NEXT:    br label [[WHILE_END]]
902 ; NO-TRANSFORM:       while.end:
903 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[X]], [[ENTRY:%.*]] ], [ [[INC_LCSSA1]], [[WHILE_END_LOOPEXIT]] ]
904 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
906 entry:
907   %cmp.x = icmp ult i32 %n, %x
908   br i1 %cmp.x, label %ph, label %while.end
911   br label %while.cond
913 while.cond:
914   %len.addr = phi i32 [ %len, %ph ], [ %inc, %while.body ]
915   %inc = add i32 %len.addr, 1
916   %cmp.not = icmp eq i32 %inc, %n
917   br i1 %cmp.not, label %while.end.loopexit, label %while.body
919 while.body:
920   %idxprom = zext i32 %inc to i64
921   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
922   %0 = load i8, ptr %arrayidx
923   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
924   %1 = load i8, ptr %arrayidx2
925   %cmp.not2 = icmp eq i8 %0, %1
926   br i1 %cmp.not2, label %while.cond, label %while.end.loopexit
928 while.end.loopexit:
929   %inc.lcssa1 = phi i32 [ %inc, %while.cond ], [ %inc, %while.body ]
930   br label %while.end
932 while.end:
933   %inc.lcssa = phi i32 [ %x, %entry ], [ %inc.lcssa1, %while.end.loopexit ]
934   ret i32 %inc.lcssa
937 define void @compare_bytes_cleanup_block(ptr %src1, ptr %src2) {
938 ; CHECK-LABEL: define void @compare_bytes_cleanup_block(
939 ; CHECK-SAME: ptr [[SRC1:%.*]], ptr [[SRC2:%.*]]) #[[ATTR0]] {
940 ; CHECK-NEXT:  entry:
941 ; CHECK-NEXT:    br label [[MISMATCH_MIN_IT_CHECK:%.*]]
942 ; CHECK:       mismatch_min_it_check:
943 ; CHECK-NEXT:    br i1 false, label [[MISMATCH_MEM_CHECK:%.*]], label [[MISMATCH_LOOP_PRE:%.*]], !prof [[PROF0]]
944 ; CHECK:       mismatch_mem_check:
945 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr [[SRC1]], i64 1
946 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[SRC2]], i64 1
947 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
948 ; CHECK-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64
949 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[SRC1]], i64 0
950 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[SRC2]], i64 0
951 ; CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[TMP4]] to i64
952 ; CHECK-NEXT:    [[TMP7:%.*]] = ptrtoint ptr [[TMP5]] to i64
953 ; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP3]], 12
954 ; CHECK-NEXT:    [[TMP9:%.*]] = lshr i64 [[TMP6]], 12
955 ; CHECK-NEXT:    [[TMP10:%.*]] = lshr i64 [[TMP2]], 12
956 ; CHECK-NEXT:    [[TMP11:%.*]] = lshr i64 [[TMP7]], 12
957 ; CHECK-NEXT:    [[TMP12:%.*]] = icmp ne i64 [[TMP8]], [[TMP9]]
958 ; CHECK-NEXT:    [[TMP13:%.*]] = icmp ne i64 [[TMP10]], [[TMP11]]
959 ; CHECK-NEXT:    [[TMP14:%.*]] = or i1 [[TMP12]], [[TMP13]]
960 ; CHECK-NEXT:    br i1 [[TMP14]], label [[MISMATCH_LOOP_PRE]], label [[MISMATCH_VEC_LOOP_PREHEADER:%.*]], !prof [[PROF1]]
961 ; CHECK:       mismatch_vec_loop_preheader:
962 ; CHECK-NEXT:    [[TMP15:%.*]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 1, i64 0)
963 ; CHECK-NEXT:    [[TMP16:%.*]] = call i64 @llvm.vscale.i64()
964 ; CHECK-NEXT:    [[TMP17:%.*]] = mul nuw nsw i64 [[TMP16]], 16
965 ; CHECK-NEXT:    br label [[MISMATCH_VEC_LOOP:%.*]]
966 ; CHECK:       mismatch_vec_loop:
967 ; CHECK-NEXT:    [[MISMATCH_VEC_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP15]], [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP26:%.*]], [[MISMATCH_VEC_LOOP_INC:%.*]] ]
968 ; CHECK-NEXT:    [[MISMATCH_VEC_INDEX:%.*]] = phi i64 [ 1, [[MISMATCH_VEC_LOOP_PREHEADER]] ], [ [[TMP25:%.*]], [[MISMATCH_VEC_LOOP_INC]] ]
969 ; CHECK-NEXT:    [[TMP18:%.*]] = getelementptr i8, ptr [[SRC1]], i64 [[MISMATCH_VEC_INDEX]]
970 ; CHECK-NEXT:    [[TMP19:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP18]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
971 ; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr i8, ptr [[SRC2]], i64 [[MISMATCH_VEC_INDEX]]
972 ; CHECK-NEXT:    [[TMP21:%.*]] = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0(ptr [[TMP20]], i32 1, <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i8> zeroinitializer)
973 ; CHECK-NEXT:    [[TMP22:%.*]] = icmp ne <vscale x 16 x i8> [[TMP19]], [[TMP21]]
974 ; CHECK-NEXT:    [[TMP23:%.*]] = select <vscale x 16 x i1> [[MISMATCH_VEC_LOOP_PRED]], <vscale x 16 x i1> [[TMP22]], <vscale x 16 x i1> zeroinitializer
975 ; CHECK-NEXT:    [[TMP24:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1(<vscale x 16 x i1> [[TMP23]])
976 ; CHECK-NEXT:    br i1 [[TMP24]], label [[MISMATCH_VEC_LOOP_FOUND:%.*]], label [[MISMATCH_VEC_LOOP_INC]]
977 ; CHECK:       mismatch_vec_loop_inc:
978 ; CHECK-NEXT:    [[TMP25]] = add nuw nsw i64 [[MISMATCH_VEC_INDEX]], [[TMP17]]
979 ; CHECK-NEXT:    [[TMP26]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[TMP25]], i64 0)
980 ; CHECK-NEXT:    [[TMP27:%.*]] = extractelement <vscale x 16 x i1> [[TMP26]], i64 0
981 ; CHECK-NEXT:    br i1 [[TMP27]], label [[MISMATCH_VEC_LOOP]], label [[MISMATCH_END:%.*]]
982 ; CHECK:       mismatch_vec_loop_found:
983 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_PRED:%.*]] = phi <vscale x 16 x i1> [ [[TMP23]], [[MISMATCH_VEC_LOOP]] ]
984 ; CHECK-NEXT:    [[MISMATCH_VEC_LAST_LOOP_PRED:%.*]] = phi <vscale x 16 x i1> [ [[MISMATCH_VEC_LOOP_PRED]], [[MISMATCH_VEC_LOOP]] ]
985 ; CHECK-NEXT:    [[MISMATCH_VEC_FOUND_INDEX:%.*]] = phi i64 [ [[MISMATCH_VEC_INDEX]], [[MISMATCH_VEC_LOOP]] ]
986 ; CHECK-NEXT:    [[TMP28:%.*]] = and <vscale x 16 x i1> [[MISMATCH_VEC_LAST_LOOP_PRED]], [[MISMATCH_VEC_FOUND_PRED]]
987 ; CHECK-NEXT:    [[TMP29:%.*]] = call i32 @llvm.experimental.cttz.elts.i32.nxv16i1(<vscale x 16 x i1> [[TMP28]], i1 true)
988 ; CHECK-NEXT:    [[TMP30:%.*]] = zext i32 [[TMP29]] to i64
989 ; CHECK-NEXT:    [[TMP31:%.*]] = add nuw nsw i64 [[MISMATCH_VEC_FOUND_INDEX]], [[TMP30]]
990 ; CHECK-NEXT:    [[TMP32:%.*]] = trunc i64 [[TMP31]] to i32
991 ; CHECK-NEXT:    br label [[MISMATCH_END]]
992 ; CHECK:       mismatch_loop_pre:
993 ; CHECK-NEXT:    br label [[MISMATCH_LOOP:%.*]]
994 ; CHECK:       mismatch_loop:
995 ; CHECK-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ 1, [[MISMATCH_LOOP_PRE]] ], [ [[TMP39:%.*]], [[MISMATCH_LOOP_INC:%.*]] ]
996 ; CHECK-NEXT:    [[TMP33:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
997 ; CHECK-NEXT:    [[TMP34:%.*]] = getelementptr i8, ptr [[SRC1]], i64 [[TMP33]]
998 ; CHECK-NEXT:    [[TMP35:%.*]] = load i8, ptr [[TMP34]], align 1
999 ; CHECK-NEXT:    [[TMP36:%.*]] = getelementptr i8, ptr [[SRC2]], i64 [[TMP33]]
1000 ; CHECK-NEXT:    [[TMP37:%.*]] = load i8, ptr [[TMP36]], align 1
1001 ; CHECK-NEXT:    [[TMP38:%.*]] = icmp eq i8 [[TMP35]], [[TMP37]]
1002 ; CHECK-NEXT:    br i1 [[TMP38]], label [[MISMATCH_LOOP_INC]], label [[MISMATCH_END]]
1003 ; CHECK:       mismatch_loop_inc:
1004 ; CHECK-NEXT:    [[TMP39]] = add i32 [[MISMATCH_INDEX]], 1
1005 ; CHECK-NEXT:    [[TMP40:%.*]] = icmp eq i32 [[TMP39]], 0
1006 ; CHECK-NEXT:    br i1 [[TMP40]], label [[MISMATCH_END]], label [[MISMATCH_LOOP]]
1007 ; CHECK:       mismatch_end:
1008 ; CHECK-NEXT:    [[MISMATCH_RESULT:%.*]] = phi i32 [ 0, [[MISMATCH_LOOP_INC]] ], [ [[MISMATCH_INDEX]], [[MISMATCH_LOOP]] ], [ 0, [[MISMATCH_VEC_LOOP_INC]] ], [ [[TMP32]], [[MISMATCH_VEC_LOOP_FOUND]] ]
1009 ; CHECK-NEXT:    br i1 true, label [[BYTE_COMPARE:%.*]], label [[WHILE_COND:%.*]]
1010 ; CHECK:       while.cond:
1011 ; CHECK-NEXT:    [[LEN:%.*]] = phi i32 [ [[MISMATCH_RESULT]], [[WHILE_BODY:%.*]] ], [ 0, [[MISMATCH_END]] ]
1012 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LEN]], 1
1013 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], 0
1014 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[CLEANUP_THREAD:%.*]], label [[WHILE_BODY]]
1015 ; CHECK:       while.body:
1016 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MISMATCH_RESULT]] to i64
1017 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr i8, ptr [[SRC1]], i64 [[IDXPROM]]
1018 ; CHECK-NEXT:    [[TMP41:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1019 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr i8, ptr [[SRC2]], i64 [[IDXPROM]]
1020 ; CHECK-NEXT:    [[TMP42:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1021 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP41]], [[TMP42]]
1022 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[IF_END:%.*]]
1023 ; CHECK:       byte.compare:
1024 ; CHECK-NEXT:    [[TMP43:%.*]] = icmp eq i32 [[MISMATCH_RESULT]], 0
1025 ; CHECK-NEXT:    br i1 [[TMP43]], label [[CLEANUP_THREAD]], label [[IF_END]]
1026 ; CHECK:       cleanup.thread:
1027 ; CHECK-NEXT:    ret void
1028 ; CHECK:       if.end:
1029 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[MISMATCH_RESULT]], [[WHILE_BODY]] ], [ [[MISMATCH_RESULT]], [[BYTE_COMPARE]] ]
1030 ; CHECK-NEXT:    ret void
1032 ; LOOP-DEL-LABEL: define void @compare_bytes_cleanup_block(
1033 ; LOOP-DEL-SAME: ptr [[SRC1:%.*]], ptr [[SRC2:%.*]]) #[[ATTR0]] {
1034 ; LOOP-DEL-NEXT:  entry:
1035 ; LOOP-DEL-NEXT:    br label [[MISMATCH_LOOP:%.*]]
1036 ; LOOP-DEL:       mismatch_loop:
1037 ; LOOP-DEL-NEXT:    [[MISMATCH_INDEX:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[TMP6:%.*]], [[MISMATCH_LOOP]] ]
1038 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = zext i32 [[MISMATCH_INDEX]] to i64
1039 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[SRC1]], i64 [[TMP0]]
1040 ; LOOP-DEL-NEXT:    [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
1041 ; LOOP-DEL-NEXT:    [[TMP3:%.*]] = getelementptr i8, ptr [[SRC2]], i64 [[TMP0]]
1042 ; LOOP-DEL-NEXT:    [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
1043 ; LOOP-DEL-NEXT:    [[TMP5:%.*]] = icmp ne i8 [[TMP2]], [[TMP4]]
1044 ; LOOP-DEL-NEXT:    [[TMP6]] = add i32 [[MISMATCH_INDEX]], 1
1045 ; LOOP-DEL-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0
1046 ; LOOP-DEL-NEXT:    [[OR_COND:%.*]] = or i1 [[TMP5]], [[TMP7]]
1047 ; LOOP-DEL-NEXT:    br i1 [[OR_COND]], label [[COMMON_RET:%.*]], label [[MISMATCH_LOOP]]
1048 ; LOOP-DEL:       common.ret:
1049 ; LOOP-DEL-NEXT:    ret void
1051 ; NO-TRANSFORM-LABEL: define void @compare_bytes_cleanup_block(
1052 ; NO-TRANSFORM-SAME: ptr [[SRC1:%.*]], ptr [[SRC2:%.*]]) {
1053 ; NO-TRANSFORM-NEXT:  entry:
1054 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1055 ; NO-TRANSFORM:       while.cond:
1056 ; NO-TRANSFORM-NEXT:    [[LEN:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
1057 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN]], 1
1058 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], 0
1059 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[CLEANUP_THREAD:%.*]], label [[WHILE_BODY]]
1060 ; NO-TRANSFORM:       while.body:
1061 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1062 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr i8, ptr [[SRC1]], i64 [[IDXPROM]]
1063 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1064 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr i8, ptr [[SRC2]], i64 [[IDXPROM]]
1065 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1066 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1067 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[IF_END:%.*]]
1068 ; NO-TRANSFORM:       cleanup.thread:
1069 ; NO-TRANSFORM-NEXT:    ret void
1070 ; NO-TRANSFORM:       if.end:
1071 ; NO-TRANSFORM-NEXT:    [[RES:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
1072 ; NO-TRANSFORM-NEXT:    ret void
1074 entry:
1075   br label %while.cond
1077 while.cond:
1078   %len = phi i32 [ %inc, %while.body ], [ 0, %entry ]
1079   %inc = add i32 %len, 1
1080   %cmp.not = icmp eq i32 %inc, 0
1081   br i1 %cmp.not, label %cleanup.thread, label %while.body
1083 while.body:
1084   %idxprom = zext i32 %inc to i64
1085   %arrayidx = getelementptr i8, ptr %src1, i64 %idxprom
1086   %0 = load i8, ptr %arrayidx, align 1
1087   %arrayidx2 = getelementptr i8, ptr %src2, i64 %idxprom
1088   %1 = load i8, ptr %arrayidx2, align 1
1089   %cmp.not2 = icmp eq i8 %0, %1
1090   br i1 %cmp.not2, label %while.cond, label %if.end
1092 cleanup.thread:
1093   ret void
1095 if.end:
1096   %res = phi i32 [ %inc, %while.body ]
1097   ret void
1101 ; NEGATIVE TESTS
1105 ; Similar to @compare_bytes_simple, except in the while.end block we have an extra PHI
1106 ; with unique values for each incoming block from the loop.
1107 define i32 @compare_bytes_simple2(ptr %a, ptr %b, ptr %c, ptr %d, i32 %len, i32 %n) {
1108 ; CHECK-LABEL: define i32 @compare_bytes_simple2(
1109 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1110 ; CHECK-NEXT:  entry:
1111 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1112 ; CHECK:       while.cond:
1113 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1114 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1115 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1116 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1117 ; CHECK:       while.body:
1118 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1119 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1120 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1121 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1122 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1123 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1124 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1125 ; CHECK:       while.end:
1126 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1127 ; CHECK-NEXT:    [[FINAL_PTR:%.*]] = phi ptr [ [[C]], [[WHILE_BODY]] ], [ [[D]], [[WHILE_COND]] ]
1128 ; CHECK-NEXT:    store i32 [[INC_LCSSA]], ptr [[FINAL_PTR]], align 4
1129 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1131 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple2(
1132 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1133 ; LOOP-DEL-NEXT:  entry:
1134 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1135 ; LOOP-DEL:       while.cond:
1136 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1137 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1138 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1139 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1140 ; LOOP-DEL:       while.body:
1141 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1142 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1143 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1144 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1145 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1146 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1147 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1148 ; LOOP-DEL:       while.end:
1149 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1150 ; LOOP-DEL-NEXT:    [[FINAL_PTR:%.*]] = phi ptr [ [[C]], [[WHILE_BODY]] ], [ [[D]], [[WHILE_COND]] ]
1151 ; LOOP-DEL-NEXT:    store i32 [[INC_LCSSA]], ptr [[FINAL_PTR]], align 4
1152 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1154 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple2(
1155 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1156 ; NO-TRANSFORM-NEXT:  entry:
1157 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1158 ; NO-TRANSFORM:       while.cond:
1159 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1160 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1161 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1162 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1163 ; NO-TRANSFORM:       while.body:
1164 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1165 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1166 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1167 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1168 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1169 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1170 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1171 ; NO-TRANSFORM:       while.end:
1172 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1173 ; NO-TRANSFORM-NEXT:    [[FINAL_PTR:%.*]] = phi ptr [ [[C]], [[WHILE_BODY]] ], [ [[D]], [[WHILE_COND]] ]
1174 ; NO-TRANSFORM-NEXT:    store i32 [[INC_LCSSA]], ptr [[FINAL_PTR]], align 4
1175 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1177 entry:
1178   br label %while.cond
1180 while.cond:
1181   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1182   %inc = add i32 %len.addr, 1
1183   %cmp.not = icmp eq i32 %inc, %n
1184   br i1 %cmp.not, label %while.end, label %while.body
1186 while.body:
1187   %idxprom = zext i32 %inc to i64
1188   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1189   %0 = load i8, ptr %arrayidx
1190   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1191   %1 = load i8, ptr %arrayidx2
1192   %cmp.not2 = icmp eq i8 %0, %1
1193   br i1 %cmp.not2, label %while.cond, label %while.end
1195 while.end:
1196   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1197   %final_ptr = phi ptr [ %c, %while.body ], [ %d, %while.cond ]
1198   store i32 %inc.lcssa, ptr %final_ptr
1199   ret i32 %inc.lcssa
1203 ; Similar to @compare_bytes_simple, except in the while.end block we have an extra PHI
1204 ; with unique values for each incoming block from the loop.
1205 define i32 @compare_bytes_simple3(ptr %a, ptr %b, ptr %c, i32 %d, i32 %len, i32 %n) {
1206 ; CHECK-LABEL: define i32 @compare_bytes_simple3(
1207 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1208 ; CHECK-NEXT:  entry:
1209 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1210 ; CHECK:       while.cond:
1211 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1212 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1213 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1214 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1215 ; CHECK:       while.body:
1216 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1217 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1218 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1219 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1220 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1221 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1222 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1223 ; CHECK:       while.end:
1224 ; CHECK-NEXT:    [[FINAL_VAL:%.*]] = phi i32 [ [[D]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1225 ; CHECK-NEXT:    store i32 [[FINAL_VAL]], ptr [[C]], align 4
1226 ; CHECK-NEXT:    ret i32 [[FINAL_VAL]]
1228 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple3(
1229 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1230 ; LOOP-DEL-NEXT:  entry:
1231 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1232 ; LOOP-DEL:       while.cond:
1233 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1234 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1235 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1236 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1237 ; LOOP-DEL:       while.body:
1238 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1239 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1240 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1241 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1242 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1243 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1244 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1245 ; LOOP-DEL:       while.end:
1246 ; LOOP-DEL-NEXT:    [[FINAL_VAL:%.*]] = phi i32 [ [[D]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1247 ; LOOP-DEL-NEXT:    store i32 [[FINAL_VAL]], ptr [[C]], align 4
1248 ; LOOP-DEL-NEXT:    ret i32 [[FINAL_VAL]]
1250 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple3(
1251 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1252 ; NO-TRANSFORM-NEXT:  entry:
1253 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1254 ; NO-TRANSFORM:       while.cond:
1255 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1256 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1257 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1258 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1259 ; NO-TRANSFORM:       while.body:
1260 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1261 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1262 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1263 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1264 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1265 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1266 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1267 ; NO-TRANSFORM:       while.end:
1268 ; NO-TRANSFORM-NEXT:    [[FINAL_VAL:%.*]] = phi i32 [ [[D]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1269 ; NO-TRANSFORM-NEXT:    store i32 [[FINAL_VAL]], ptr [[C]], align 4
1270 ; NO-TRANSFORM-NEXT:    ret i32 [[FINAL_VAL]]
1272 entry:
1273   br label %while.cond
1275 while.cond:
1276   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1277   %inc = add i32 %len.addr, 1
1278   %cmp.not = icmp eq i32 %inc, %n
1279   br i1 %cmp.not, label %while.end, label %while.body
1281 while.body:
1282   %idxprom = zext i32 %inc to i64
1283   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1284   %0 = load i8, ptr %arrayidx
1285   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1286   %1 = load i8, ptr %arrayidx2
1287   %cmp.not2 = icmp eq i8 %0, %1
1288   br i1 %cmp.not2, label %while.cond, label %while.end
1290 while.end:
1291   %final_val = phi i32 [ %d, %while.body ], [ %inc, %while.cond ]
1292   store i32 %final_val, ptr %c
1293   ret i32 %final_val
1297 define i32 @compare_bytes_sign_ext(ptr %a, ptr %b, i32 %len, i32 %n) {
1298 ; CHECK-LABEL: define i32 @compare_bytes_sign_ext(
1299 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1300 ; CHECK-NEXT:  entry:
1301 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1302 ; CHECK:       while.cond:
1303 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1304 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1305 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1306 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1307 ; CHECK:       while.body:
1308 ; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[INC]] to i64
1309 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1310 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1311 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1312 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1313 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1314 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1315 ; CHECK:       while.end:
1316 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1317 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1319 ; LOOP-DEL-LABEL: define i32 @compare_bytes_sign_ext(
1320 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1321 ; LOOP-DEL-NEXT:  entry:
1322 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1323 ; LOOP-DEL:       while.cond:
1324 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1325 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1326 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1327 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1328 ; LOOP-DEL:       while.body:
1329 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = sext i32 [[INC]] to i64
1330 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1331 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1332 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1333 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1334 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1335 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1336 ; LOOP-DEL:       while.end:
1337 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1338 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1340 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_sign_ext(
1341 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1342 ; NO-TRANSFORM-NEXT:  entry:
1343 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1344 ; NO-TRANSFORM:       while.cond:
1345 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1346 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1347 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1348 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1349 ; NO-TRANSFORM:       while.body:
1350 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = sext i32 [[INC]] to i64
1351 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1352 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1353 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1354 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1355 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1356 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1357 ; NO-TRANSFORM:       while.end:
1358 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1359 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1361 entry:
1362   br label %while.cond
1364 while.cond:
1365   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1366   %inc = add i32 %len.addr, 1
1367   %cmp.not = icmp eq i32 %inc, %n
1368   br i1 %cmp.not, label %while.end, label %while.body
1370 while.body:
1371   %idxprom = sext i32 %inc to i64
1372   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1373   %0 = load i8, ptr %arrayidx
1374   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1375   %1 = load i8, ptr %arrayidx2
1376   %cmp.not2 = icmp eq i8 %0, %1
1377   br i1 %cmp.not2, label %while.cond, label %while.end
1379 while.end:
1380   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1381   ret i32 %inc.lcssa
1385 define i32 @compare_bytes_outside_uses(ptr %a, ptr %b, i32 %len, i32 %n) {
1386 ; CHECK-LABEL: define i32 @compare_bytes_outside_uses(
1387 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1388 ; CHECK-NEXT:  entry:
1389 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1390 ; CHECK:       while.cond:
1391 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1392 ; CHECK-NEXT:    [[INC]] = add i32 [[IV]], 1
1393 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[LEN]]
1394 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1395 ; CHECK:       while.body:
1396 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1397 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1398 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1399 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1400 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1401 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1402 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1403 ; CHECK:       while.end:
1404 ; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ [[CMP_NOT2]], [[WHILE_BODY]] ], [ [[CMP_NOT]], [[WHILE_COND]] ]
1405 ; CHECK-NEXT:    [[EXT_RES:%.*]] = zext i1 [[RES]] to i32
1406 ; CHECK-NEXT:    ret i32 [[EXT_RES]]
1408 ; LOOP-DEL-LABEL: define i32 @compare_bytes_outside_uses(
1409 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1410 ; LOOP-DEL-NEXT:  entry:
1411 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1412 ; LOOP-DEL:       while.cond:
1413 ; LOOP-DEL-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1414 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[IV]], 1
1415 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[LEN]]
1416 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1417 ; LOOP-DEL:       while.body:
1418 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1419 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1420 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1421 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1422 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1423 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1424 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1425 ; LOOP-DEL:       while.end:
1426 ; LOOP-DEL-NEXT:    [[RES:%.*]] = phi i1 [ [[CMP_NOT2]], [[WHILE_BODY]] ], [ [[CMP_NOT]], [[WHILE_COND]] ]
1427 ; LOOP-DEL-NEXT:    [[EXT_RES:%.*]] = zext i1 [[RES]] to i32
1428 ; LOOP-DEL-NEXT:    ret i32 [[EXT_RES]]
1430 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_outside_uses(
1431 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1432 ; NO-TRANSFORM-NEXT:  entry:
1433 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1434 ; NO-TRANSFORM:       while.cond:
1435 ; NO-TRANSFORM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1436 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[IV]], 1
1437 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[LEN]]
1438 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1439 ; NO-TRANSFORM:       while.body:
1440 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1441 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1442 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1443 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1444 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1445 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1446 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1447 ; NO-TRANSFORM:       while.end:
1448 ; NO-TRANSFORM-NEXT:    [[RES:%.*]] = phi i1 [ [[CMP_NOT2]], [[WHILE_BODY]] ], [ [[CMP_NOT]], [[WHILE_COND]] ]
1449 ; NO-TRANSFORM-NEXT:    [[EXT_RES:%.*]] = zext i1 [[RES]] to i32
1450 ; NO-TRANSFORM-NEXT:    ret i32 [[EXT_RES]]
1452 entry:
1453   br label %while.cond
1455 while.cond:
1456   %iv = phi i32 [ 0, %entry ], [ %inc, %while.body ]
1457   %inc = add i32 %iv, 1
1458   %cmp.not = icmp eq i32 %inc, %len
1459   br i1 %cmp.not, label %while.end, label %while.body
1461 while.body:
1462   %idxprom = zext i32 %inc to i64
1463   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1464   %0 = load i8, ptr %arrayidx
1465   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1466   %1 = load i8, ptr %arrayidx2
1467   %cmp.not2 = icmp eq i8 %0, %1
1468   br i1 %cmp.not2, label %while.cond, label %while.end
1470 while.end:
1471   %res = phi i1 [ %cmp.not2, %while.body ], [ %cmp.not, %while.cond ]
1472   %ext_res = zext i1 %res to i32
1473   ret i32 %ext_res
1476 define i64 @compare_bytes_i64_index(ptr %a, ptr %b, i64 %len, i64 %n) {
1477 ; CHECK-LABEL: define i64 @compare_bytes_i64_index(
1478 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[LEN:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
1479 ; CHECK-NEXT:  entry:
1480 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1481 ; CHECK:       while.cond:
1482 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i64 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1483 ; CHECK-NEXT:    [[INC]] = add i64 [[LEN_ADDR]], 1
1484 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
1485 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1486 ; CHECK:       while.body:
1487 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INC]]
1488 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1489 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[INC]]
1490 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1491 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1492 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1493 ; CHECK:       while.end:
1494 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1495 ; CHECK-NEXT:    ret i64 [[INC_LCSSA]]
1497 ; LOOP-DEL-LABEL: define i64 @compare_bytes_i64_index(
1498 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[LEN:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
1499 ; LOOP-DEL-NEXT:  entry:
1500 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1501 ; LOOP-DEL:       while.cond:
1502 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i64 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1503 ; LOOP-DEL-NEXT:    [[INC]] = add i64 [[LEN_ADDR]], 1
1504 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
1505 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1506 ; LOOP-DEL:       while.body:
1507 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INC]]
1508 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1509 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[INC]]
1510 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1511 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1512 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1513 ; LOOP-DEL:       while.end:
1514 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1515 ; LOOP-DEL-NEXT:    ret i64 [[INC_LCSSA]]
1517 ; NO-TRANSFORM-LABEL: define i64 @compare_bytes_i64_index(
1518 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[LEN:%.*]], i64 [[N:%.*]]) {
1519 ; NO-TRANSFORM-NEXT:  entry:
1520 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1521 ; NO-TRANSFORM:       while.cond:
1522 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i64 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1523 ; NO-TRANSFORM-NEXT:    [[INC]] = add i64 [[LEN_ADDR]], 1
1524 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
1525 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1526 ; NO-TRANSFORM:       while.body:
1527 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INC]]
1528 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1529 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[INC]]
1530 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1531 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1532 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1533 ; NO-TRANSFORM:       while.end:
1534 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1535 ; NO-TRANSFORM-NEXT:    ret i64 [[INC_LCSSA]]
1537 entry:
1538   br label %while.cond
1540 while.cond:
1541   %len.addr = phi i64 [ %len, %entry ], [ %inc, %while.body ]
1542   %inc = add i64 %len.addr, 1
1543   %cmp.not = icmp eq i64 %inc, %n
1544   br i1 %cmp.not, label %while.end, label %while.body
1546 while.body:
1547   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %inc
1548   %0 = load i8, ptr %arrayidx
1549   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %inc
1550   %1 = load i8, ptr %arrayidx2
1551   %cmp.not2 = icmp eq i8 %0, %1
1552   br i1 %cmp.not2, label %while.cond, label %while.end
1554 while.end:
1555   %inc.lcssa = phi i64 [ %inc, %while.body ], [ %inc, %while.cond ]
1556   ret i64 %inc.lcssa
1559 define i32 @compare_bytes_simple_wrong_icmp1(ptr %a, ptr %b, i32 %len, i32 %n) {
1560 ; CHECK-LABEL: define i32 @compare_bytes_simple_wrong_icmp1(
1561 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1562 ; CHECK-NEXT:  entry:
1563 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1564 ; CHECK:       while.cond:
1565 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1566 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1567 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp ne i32 [[INC]], [[N]]
1568 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1569 ; CHECK:       while.body:
1570 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1571 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1572 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1573 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1574 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1575 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1576 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1577 ; CHECK:       while.end:
1578 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1579 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1581 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple_wrong_icmp1(
1582 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1583 ; LOOP-DEL-NEXT:  entry:
1584 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1585 ; LOOP-DEL:       while.cond:
1586 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1587 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1588 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp ne i32 [[INC]], [[N]]
1589 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1590 ; LOOP-DEL:       while.body:
1591 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1592 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1593 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1594 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1595 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1596 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1597 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1598 ; LOOP-DEL:       while.end:
1599 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1600 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1602 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple_wrong_icmp1(
1603 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1604 ; NO-TRANSFORM-NEXT:  entry:
1605 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1606 ; NO-TRANSFORM:       while.cond:
1607 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1608 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1609 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp ne i32 [[INC]], [[N]]
1610 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1611 ; NO-TRANSFORM:       while.body:
1612 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1613 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1614 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1615 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1616 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1617 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1618 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1619 ; NO-TRANSFORM:       while.end:
1620 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1621 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1623 entry:
1624   br label %while.cond
1626 while.cond:
1627   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1628   %inc = add i32 %len.addr, 1
1629   %cmp.not = icmp ne i32 %inc, %n
1630   br i1 %cmp.not, label %while.end, label %while.body
1632 while.body:
1633   %idxprom = zext i32 %inc to i64
1634   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1635   %0 = load i8, ptr %arrayidx
1636   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1637   %1 = load i8, ptr %arrayidx2
1638   %cmp.not2 = icmp eq i8 %0, %1
1639   br i1 %cmp.not2, label %while.cond, label %while.end
1641 while.end:
1642   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1643   ret i32 %inc.lcssa
1646 define i32 @compare_bytes_simple_wrong_icmp2(ptr %a, ptr %b, i32 %len, i32 %n) {
1647 ; CHECK-LABEL: define i32 @compare_bytes_simple_wrong_icmp2(
1648 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1649 ; CHECK-NEXT:  entry:
1650 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1651 ; CHECK:       while.cond:
1652 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1653 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1654 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1655 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_BODY]], label [[WHILE_END:%.*]]
1656 ; CHECK:       while.body:
1657 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1658 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1659 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1660 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1661 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1662 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1663 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1664 ; CHECK:       while.end:
1665 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1666 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1668 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple_wrong_icmp2(
1669 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1670 ; LOOP-DEL-NEXT:  entry:
1671 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1672 ; LOOP-DEL:       while.cond:
1673 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1674 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1675 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1676 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_BODY]], label [[WHILE_END:%.*]]
1677 ; LOOP-DEL:       while.body:
1678 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1679 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1680 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1681 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1682 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1683 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1684 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1685 ; LOOP-DEL:       while.end:
1686 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1687 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1689 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple_wrong_icmp2(
1690 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1691 ; NO-TRANSFORM-NEXT:  entry:
1692 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1693 ; NO-TRANSFORM:       while.cond:
1694 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1695 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1696 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1697 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_BODY]], label [[WHILE_END:%.*]]
1698 ; NO-TRANSFORM:       while.body:
1699 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1700 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1701 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1702 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1703 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1704 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1705 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1706 ; NO-TRANSFORM:       while.end:
1707 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1708 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1710 entry:
1711   br label %while.cond
1713 while.cond:
1714   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1715   %inc = add i32 %len.addr, 1
1716   %cmp.not = icmp eq i32 %inc, %n
1717   br i1 %cmp.not, label %while.body, label %while.end
1719 while.body:
1720   %idxprom = zext i32 %inc to i64
1721   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1722   %0 = load i8, ptr %arrayidx
1723   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1724   %1 = load i8, ptr %arrayidx2
1725   %cmp.not2 = icmp eq i8 %0, %1
1726   br i1 %cmp.not2, label %while.cond, label %while.end
1728 while.end:
1729   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1730   ret i32 %inc.lcssa
1733 define i32 @compare_bytes_simple_wrong_icmp3(ptr %a, ptr %b, i32 %len, i32 %n) {
1734 ; CHECK-LABEL: define i32 @compare_bytes_simple_wrong_icmp3(
1735 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1736 ; CHECK-NEXT:  entry:
1737 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1738 ; CHECK:       while.cond:
1739 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1740 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1741 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1742 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1743 ; CHECK:       while.body:
1744 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1745 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1746 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1747 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1748 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1749 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp ne i8 [[TMP0]], [[TMP1]]
1750 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1751 ; CHECK:       while.end:
1752 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1753 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1755 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple_wrong_icmp3(
1756 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1757 ; LOOP-DEL-NEXT:  entry:
1758 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1759 ; LOOP-DEL:       while.cond:
1760 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1761 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1762 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1763 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1764 ; LOOP-DEL:       while.body:
1765 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1766 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1767 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1768 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1769 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1770 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp ne i8 [[TMP0]], [[TMP1]]
1771 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1772 ; LOOP-DEL:       while.end:
1773 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1774 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1776 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple_wrong_icmp3(
1777 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1778 ; NO-TRANSFORM-NEXT:  entry:
1779 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1780 ; NO-TRANSFORM:       while.cond:
1781 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1782 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1783 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1784 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1785 ; NO-TRANSFORM:       while.body:
1786 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1787 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1788 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1789 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1790 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1791 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp ne i8 [[TMP0]], [[TMP1]]
1792 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1793 ; NO-TRANSFORM:       while.end:
1794 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1795 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1797 entry:
1798   br label %while.cond
1800 while.cond:
1801   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1802   %inc = add i32 %len.addr, 1
1803   %cmp.not = icmp eq i32 %inc, %n
1804   br i1 %cmp.not, label %while.end, label %while.body
1806 while.body:
1807   %idxprom = zext i32 %inc to i64
1808   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1809   %0 = load i8, ptr %arrayidx
1810   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1811   %1 = load i8, ptr %arrayidx2
1812   %cmp.not2 = icmp ne i8 %0, %1
1813   br i1 %cmp.not2, label %while.cond, label %while.end
1815 while.end:
1816   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1817   ret i32 %inc.lcssa
1820 define i32 @compare_bytes_simple_wrong_icmp4(ptr %a, ptr %b, i32 %len, i32 %n) {
1821 ; CHECK-LABEL: define i32 @compare_bytes_simple_wrong_icmp4(
1822 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1823 ; CHECK-NEXT:  entry:
1824 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1825 ; CHECK:       while.cond:
1826 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1827 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1828 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1829 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1830 ; CHECK:       while.body:
1831 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1832 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1833 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1834 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1835 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1836 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1837 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_END]], label [[WHILE_COND]]
1838 ; CHECK:       while.end:
1839 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1840 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1842 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple_wrong_icmp4(
1843 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1844 ; LOOP-DEL-NEXT:  entry:
1845 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1846 ; LOOP-DEL:       while.cond:
1847 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1848 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1849 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1850 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1851 ; LOOP-DEL:       while.body:
1852 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1853 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1854 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1855 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1856 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1857 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1858 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_END]], label [[WHILE_COND]]
1859 ; LOOP-DEL:       while.end:
1860 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1861 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1863 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple_wrong_icmp4(
1864 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1865 ; NO-TRANSFORM-NEXT:  entry:
1866 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1867 ; NO-TRANSFORM:       while.cond:
1868 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1869 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1870 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1871 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1872 ; NO-TRANSFORM:       while.body:
1873 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1874 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1875 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1876 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1877 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
1878 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
1879 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_END]], label [[WHILE_COND]]
1880 ; NO-TRANSFORM:       while.end:
1881 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1882 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1884 entry:
1885   br label %while.cond
1887 while.cond:
1888   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1889   %inc = add i32 %len.addr, 1
1890   %cmp.not = icmp eq i32 %inc, %n
1891   br i1 %cmp.not, label %while.end, label %while.body
1893 while.body:
1894   %idxprom = zext i32 %inc to i64
1895   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1896   %0 = load i8, ptr %arrayidx
1897   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1898   %1 = load i8, ptr %arrayidx2
1899   %cmp.not2 = icmp eq i8 %0, %1
1900   br i1 %cmp.not2, label %while.end, label %while.cond
1902 while.end:
1903   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1904   ret i32 %inc.lcssa
1907 define i32 @compare_bytes_bad_load_type(ptr %a, ptr %b, i32 %len, i32 %n) {
1908 ; CHECK-LABEL: define i32 @compare_bytes_bad_load_type(
1909 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1910 ; CHECK-NEXT:  entry:
1911 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
1912 ; CHECK:       while.cond:
1913 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1914 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1915 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1916 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1917 ; CHECK:       while.body:
1918 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1919 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1920 ; CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
1921 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1922 ; CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX2]], align 2
1923 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i16 [[TMP0]], [[TMP1]]
1924 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1925 ; CHECK:       while.end:
1926 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1927 ; CHECK-NEXT:    ret i32 [[INC_LCSSA]]
1929 ; LOOP-DEL-LABEL: define i32 @compare_bytes_bad_load_type(
1930 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
1931 ; LOOP-DEL-NEXT:  entry:
1932 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
1933 ; LOOP-DEL:       while.cond:
1934 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1935 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1936 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1937 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1938 ; LOOP-DEL:       while.body:
1939 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1940 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1941 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
1942 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1943 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX2]], align 2
1944 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i16 [[TMP0]], [[TMP1]]
1945 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1946 ; LOOP-DEL:       while.end:
1947 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1948 ; LOOP-DEL-NEXT:    ret i32 [[INC_LCSSA]]
1950 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_bad_load_type(
1951 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[N:%.*]]) {
1952 ; NO-TRANSFORM-NEXT:  entry:
1953 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
1954 ; NO-TRANSFORM:       while.cond:
1955 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
1956 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
1957 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
1958 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
1959 ; NO-TRANSFORM:       while.body:
1960 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
1961 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
1962 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
1963 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
1964 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX2]], align 2
1965 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i16 [[TMP0]], [[TMP1]]
1966 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
1967 ; NO-TRANSFORM:       while.end:
1968 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
1969 ; NO-TRANSFORM-NEXT:    ret i32 [[INC_LCSSA]]
1971 entry:
1972   br label %while.cond
1974 while.cond:
1975   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
1976   %inc = add i32 %len.addr, 1
1977   %cmp.not = icmp eq i32 %inc, %n
1978   br i1 %cmp.not, label %while.end, label %while.body
1980 while.body:
1981   %idxprom = zext i32 %inc to i64
1982   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
1983   %0 = load i16, ptr %arrayidx
1984   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
1985   %1 = load i16, ptr %arrayidx2
1986   %cmp.not2 = icmp eq i16 %0, %1
1987   br i1 %cmp.not2, label %while.cond, label %while.end
1989 while.end:
1990   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
1991   ret i32 %inc.lcssa
1995 define i32 @compare_bytes_simple_optsize(ptr %a, ptr %b, i32 %len, i32 %extra, i32 %n) optsize {
1996 ; CHECK-LABEL: define i32 @compare_bytes_simple_optsize(
1997 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR1:[0-9]+]] {
1998 ; CHECK-NEXT:  entry:
1999 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
2000 ; CHECK:       while.cond:
2001 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2002 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
2003 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2004 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2005 ; CHECK:       while.body:
2006 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2007 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2008 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2009 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2010 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2011 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2012 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2013 ; CHECK:       while.end:
2014 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2015 ; CHECK-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2016 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2017 ; CHECK-NEXT:    ret i32 [[RES]]
2019 ; LOOP-DEL-LABEL: define i32 @compare_bytes_simple_optsize(
2020 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR1:[0-9]+]] {
2021 ; LOOP-DEL-NEXT:  entry:
2022 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
2023 ; LOOP-DEL:       while.cond:
2024 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2025 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
2026 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2027 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2028 ; LOOP-DEL:       while.body:
2029 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2030 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2031 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2032 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2033 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2034 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2035 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2036 ; LOOP-DEL:       while.end:
2037 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2038 ; LOOP-DEL-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2039 ; LOOP-DEL-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2040 ; LOOP-DEL-NEXT:    ret i32 [[RES]]
2042 ; NO-TRANSFORM-LABEL: define i32 @compare_bytes_simple_optsize(
2043 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
2044 ; NO-TRANSFORM-NEXT:  entry:
2045 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
2046 ; NO-TRANSFORM:       while.cond:
2047 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2048 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
2049 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2050 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2051 ; NO-TRANSFORM:       while.body:
2052 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2053 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2054 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2055 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2056 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2057 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2058 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2059 ; NO-TRANSFORM:       while.end:
2060 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2061 ; NO-TRANSFORM-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2062 ; NO-TRANSFORM-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2063 ; NO-TRANSFORM-NEXT:    ret i32 [[RES]]
2065 entry:
2066   br label %while.cond
2068 while.cond:
2069   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
2070   %inc = add i32 %len.addr, 1
2071   %cmp.not = icmp eq i32 %inc, %n
2072   br i1 %cmp.not, label %while.end, label %while.body
2074 while.body:
2075   %idxprom = zext i32 %inc to i64
2076   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
2077   %0 = load i8, ptr %arrayidx
2078   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
2079   %1 = load i8, ptr %arrayidx2
2080   %cmp.not2 = icmp eq i8 %0, %1
2081   br i1 %cmp.not2, label %while.cond, label %while.end
2083 while.end:
2084   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
2085   %extra.phi = phi i32 [ %extra, %while.body ], [ %extra, %while.cond ]
2086   %res = add i32 %inc.lcssa, %extra.phi
2087   ret i32 %res
2090 ; The optimization should be disabled when noimplicitfloat is present.
2091 define i32 @no_implicit_float(ptr %a, ptr %b, i32 %len, i32 %extra, i32 %n) noimplicitfloat {
2092 ; CHECK-LABEL: define i32 @no_implicit_float(
2093 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {
2094 ; CHECK-NEXT:  entry:
2095 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
2096 ; CHECK:       while.cond:
2097 ; CHECK-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2098 ; CHECK-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
2099 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2100 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2101 ; CHECK:       while.body:
2102 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2103 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2104 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2105 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2106 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2107 ; CHECK-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2108 ; CHECK-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2109 ; CHECK:       while.end:
2110 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2111 ; CHECK-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2112 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2113 ; CHECK-NEXT:    ret i32 [[RES]]
2115 ; LOOP-DEL-LABEL: define i32 @no_implicit_float(
2116 ; LOOP-DEL-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {
2117 ; LOOP-DEL-NEXT:  entry:
2118 ; LOOP-DEL-NEXT:    br label [[WHILE_COND:%.*]]
2119 ; LOOP-DEL:       while.cond:
2120 ; LOOP-DEL-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2121 ; LOOP-DEL-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
2122 ; LOOP-DEL-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2123 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2124 ; LOOP-DEL:       while.body:
2125 ; LOOP-DEL-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2126 ; LOOP-DEL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2127 ; LOOP-DEL-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2128 ; LOOP-DEL-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2129 ; LOOP-DEL-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2130 ; LOOP-DEL-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2131 ; LOOP-DEL-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2132 ; LOOP-DEL:       while.end:
2133 ; LOOP-DEL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2134 ; LOOP-DEL-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2135 ; LOOP-DEL-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2136 ; LOOP-DEL-NEXT:    ret i32 [[RES]]
2138 ; NO-TRANSFORM-LABEL: define i32 @no_implicit_float(
2139 ; NO-TRANSFORM-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i32 [[LEN:%.*]], i32 [[EXTRA:%.*]], i32 [[N:%.*]]) #[[ATTR1:[0-9]+]] {
2140 ; NO-TRANSFORM-NEXT:  entry:
2141 ; NO-TRANSFORM-NEXT:    br label [[WHILE_COND:%.*]]
2142 ; NO-TRANSFORM:       while.cond:
2143 ; NO-TRANSFORM-NEXT:    [[LEN_ADDR:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[WHILE_BODY:%.*]] ]
2144 ; NO-TRANSFORM-NEXT:    [[INC]] = add i32 [[LEN_ADDR]], 1
2145 ; NO-TRANSFORM-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
2146 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT]], label [[WHILE_END:%.*]], label [[WHILE_BODY]]
2147 ; NO-TRANSFORM:       while.body:
2148 ; NO-TRANSFORM-NEXT:    [[IDXPROM:%.*]] = zext i32 [[INC]] to i64
2149 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]]
2150 ; NO-TRANSFORM-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
2151 ; NO-TRANSFORM-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]]
2152 ; NO-TRANSFORM-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
2153 ; NO-TRANSFORM-NEXT:    [[CMP_NOT2:%.*]] = icmp eq i8 [[TMP0]], [[TMP1]]
2154 ; NO-TRANSFORM-NEXT:    br i1 [[CMP_NOT2]], label [[WHILE_COND]], label [[WHILE_END]]
2155 ; NO-TRANSFORM:       while.end:
2156 ; NO-TRANSFORM-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ], [ [[INC]], [[WHILE_COND]] ]
2157 ; NO-TRANSFORM-NEXT:    [[EXTRA_PHI:%.*]] = phi i32 [ [[EXTRA]], [[WHILE_BODY]] ], [ [[EXTRA]], [[WHILE_COND]] ]
2158 ; NO-TRANSFORM-NEXT:    [[RES:%.*]] = add i32 [[INC_LCSSA]], [[EXTRA_PHI]]
2159 ; NO-TRANSFORM-NEXT:    ret i32 [[RES]]
2161 entry:
2162   br label %while.cond
2164 while.cond:
2165   %len.addr = phi i32 [ %len, %entry ], [ %inc, %while.body ]
2166   %inc = add i32 %len.addr, 1
2167   %cmp.not = icmp eq i32 %inc, %n
2168   br i1 %cmp.not, label %while.end, label %while.body
2170 while.body:
2171   %idxprom = zext i32 %inc to i64
2172   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
2173   %0 = load i8, ptr %arrayidx
2174   %arrayidx2 = getelementptr inbounds i8, ptr %b, i64 %idxprom
2175   %1 = load i8, ptr %arrayidx2
2176   %cmp.not2 = icmp eq i8 %0, %1
2177   br i1 %cmp.not2, label %while.cond, label %while.end
2179 while.end:
2180   %inc.lcssa = phi i32 [ %inc, %while.body ], [ %inc, %while.cond ]
2181   %extra.phi = phi i32 [ %extra, %while.body ], [ %extra, %while.cond ]
2182   %res = add i32 %inc.lcssa, %extra.phi
2183   ret i32 %res