1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -select-optimize -mtriple=arm64-apple-macosx -S %s | FileCheck %s 3; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=arm64-apple-macosx -S %s | FileCheck %s 4 5define void @test_add_zext(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 6; CHECK-LABEL: @test_add_zext( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: br label [[LOOP:%.*]] 9; CHECK: loop: 10; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 11; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 12; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 13; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 14; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 15; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 16; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 17; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 18; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i64 19; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 20; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]] 21; CHECK: select.true.sink: 22; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], 1 23; CHECK-NEXT: br label [[SELECT_END]] 24; CHECK: select.end: 25; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ] 26; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 27; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 28; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 29; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 30; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 31; CHECK: exit: 32; CHECK-NEXT: ret void 33; 34entry: 35 br label %loop 36 37loop: 38 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 39 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 40 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 41 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 42 %l.i = load ptr, ptr %gep.i, align 8 43 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 44 %l.j = load ptr, ptr %gep.j, align 8 45 %cmp3 = icmp ult ptr %l.i, %l.j 46 %dec = zext i1 %cmp3 to i64 47 %j.next = add nsw i64 %j, %dec 48 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 49 store i64 %j.next, ptr %gep.dst, align 8 50 %iv.next = add i64 %iv, 1 51 %ec = icmp eq i64 %iv, %j.start 52 br i1 %ec, label %exit, label %loop 53 54exit: 55 ret void 56} 57 58define void @test_add_zext_first_op(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 59; CHECK-LABEL: @test_add_zext_first_op( 60; CHECK-NEXT: entry: 61; CHECK-NEXT: br label [[LOOP:%.*]] 62; CHECK: loop: 63; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 64; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_START:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 65; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 66; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 67; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_DST]], align 8 68; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 [[J]] 69; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 70; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 71; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i64 72; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 73; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]] 74; CHECK: select.true.sink: 75; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 1, [[J]] 76; CHECK-NEXT: br label [[SELECT_END]] 77; CHECK: select.end: 78; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ] 79; CHECK-NEXT: [[GEP_DST1:%.*]] = getelementptr inbounds ptr, ptr [[DST1:%.*]], i64 [[IV1]] 80; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST1]], align 8 81; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 1 82; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV1]], [[J_START]] 83; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 84; CHECK: exit: 85; CHECK-NEXT: ret void 86; 87entry: 88 br label %loop 89 90loop: 91 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 92 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 93 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 94 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 95 %l.i = load ptr, ptr %gep.i, align 8 96 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 97 %l.j = load ptr, ptr %gep.j, align 8 98 %cmp3 = icmp ult ptr %l.i, %l.j 99 %dec = zext i1 %cmp3 to i64 100 %j.next = add nsw i64 %dec, %j 101 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 102 store i64 %j.next, ptr %gep.dst, align 8 103 %iv.next = add i64 %iv, 1 104 %ec = icmp eq i64 %iv, %j.start 105 br i1 %ec, label %exit, label %loop 106 107exit: 108 ret void 109} 110 111define void @test_add_zext_not(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 112; CHECK-LABEL: @test_add_zext_not( 113; CHECK-NEXT: entry: 114; CHECK-NEXT: br label [[LOOP:%.*]] 115; CHECK: loop: 116; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 117; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_START:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 118; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 119; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 120; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 121; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 122; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 123; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 124; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 125; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[NOT_CMP3]] to i64 126; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 127; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE_SINK:%.*]] 128; CHECK: select.false.sink: 129; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], 1 130; CHECK-NEXT: br label [[SELECT_END]] 131; CHECK: select.end: 132; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE_SINK]] ] 133; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 134; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 135; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 136; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[J_START]] 137; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 138; CHECK: exit: 139; CHECK-NEXT: ret void 140; 141entry: 142 br label %loop 143 144loop: 145 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 146 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 147 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 148 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 149 %l.i = load ptr, ptr %gep.i, align 8 150 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 151 %l.j = load ptr, ptr %gep.j, align 8 152 %cmp3 = icmp ult ptr %l.i, %l.j 153 %not.cmp3 = xor i1 %cmp3, true 154 %dec = zext i1 %not.cmp3 to i64 155 %j.next = add nsw i64 %j, %dec 156 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 157 store i64 %j.next, ptr %gep.dst, align 8 158 %iv.next = add i64 %iv, 1 159 %ec = icmp eq i64 %iv, %j.start 160 br i1 %ec, label %exit, label %loop 161 162exit: 163 ret void 164} 165 166define void @test_add_sext(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 167; CHECK-LABEL: @test_add_sext( 168; CHECK-NEXT: entry: 169; CHECK-NEXT: br label [[LOOP:%.*]] 170; CHECK: loop: 171; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 172; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 173; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 174; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 175; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 176; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 177; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 178; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 179; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[CMP3]] to i64 180; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 181; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]] 182; CHECK: select.true.sink: 183; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], -1 184; CHECK-NEXT: br label [[SELECT_END]] 185; CHECK: select.end: 186; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ] 187; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 188; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 189; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 190; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 191; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 192; CHECK: exit: 193; CHECK-NEXT: ret void 194; 195entry: 196 br label %loop 197 198loop: 199 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 200 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 201 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 202 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 203 %l.i = load ptr, ptr %gep.i, align 8 204 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 205 %l.j = load ptr, ptr %gep.j, align 8 206 %cmp3 = icmp ult ptr %l.i, %l.j 207 %dec = sext i1 %cmp3 to i64 208 %j.next = add nsw i64 %j, %dec 209 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 210 store i64 %j.next, ptr %gep.dst, align 8 211 %iv.next = add i64 %iv, 1 212 %ec = icmp eq i64 %iv, %j.start 213 br i1 %ec, label %exit, label %loop 214 215exit: 216 ret void 217} 218 219define void @test_add_sext_not(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 220; CHECK-LABEL: @test_add_sext_not( 221; CHECK-NEXT: entry: 222; CHECK-NEXT: br label [[LOOP:%.*]] 223; CHECK: loop: 224; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 225; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 226; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 227; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 228; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 229; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 230; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 231; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 232; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 233; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64 234; CHECK-NEXT: [[NOT_CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 235; CHECK-NEXT: br i1 [[NOT_CMP3_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]] 236; CHECK: select.false.sink: 237; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], -1 238; CHECK-NEXT: br label [[SELECT_END]] 239; CHECK: select.end: 240; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE]] ] 241; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 242; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 243; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 244; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 245; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 246; CHECK: exit: 247; CHECK-NEXT: ret void 248; 249entry: 250 br label %loop 251 252loop: 253 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 254 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 255 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 256 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 257 %l.i = load ptr, ptr %gep.i, align 8 258 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 259 %l.j = load ptr, ptr %gep.j, align 8 260 %cmp3 = icmp ult ptr %l.i, %l.j 261 %not.cmp3 = xor i1 %cmp3, true 262 %dec = sext i1 %not.cmp3 to i64 263 %j.next = add nsw i64 %j, %dec 264 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 265 store i64 %j.next, ptr %gep.dst, align 8 266 %iv.next = add i64 %iv, 1 267 %ec = icmp eq i64 %iv, %j.start 268 br i1 %ec, label %exit, label %loop 269 270exit: 271 ret void 272} 273 274define void @test_add_sext_not_and_regular_select(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 275; CHECK-LABEL: @test_add_sext_not_and_regular_select( 276; CHECK-NEXT: entry: 277; CHECK-NEXT: br label [[LOOP:%.*]] 278; CHECK: loop: 279; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ] 280; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ] 281; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ] 282; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 283; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 284; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 285; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 286; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 287; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 288; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64 289; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 290; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE_SINK:%.*]] 291; CHECK: select.false.sink: 292; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], -1 293; CHECK-NEXT: br label [[SELECT_END1]] 294; CHECK: select.end: 295; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE_SINK]] ] 296; CHECK-NEXT: [[SINK:%.*]] = phi ptr [ [[L_I]], [[LOOP]] ], [ [[L_J]], [[SELECT_FALSE_SINK]] ] 297; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 298; CHECK-NEXT: store ptr [[SINK]], ptr [[GEP_DST]], align 8 299; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 300; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 301; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 302; CHECK: exit: 303; CHECK-NEXT: ret void 304; 305entry: 306 br label %loop 307 308loop: 309 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 310 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 311 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 312 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 313 %l.i = load ptr, ptr %gep.i, align 8 314 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 315 %l.j = load ptr, ptr %gep.j, align 8 316 %cmp3 = icmp ult ptr %l.i, %l.j 317 %not.cmp3 = xor i1 %cmp3, true 318 %dec = sext i1 %not.cmp3 to i64 319 %j.next = add nsw i64 %j, %dec 320 %sink = select i1 %cmp3, ptr %l.i, ptr %l.j 321 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 322 store ptr %sink, ptr %gep.dst, align 8 323 %iv.next = add i64 %iv, 1 324 %ec = icmp eq i64 %iv, %j.start 325 br i1 %ec, label %exit, label %loop 326 327exit: 328 ret void 329} 330 331define void @test_add_sext_not_and_regular_select2(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 332; CHECK-LABEL: @test_add_sext_not_and_regular_select2( 333; CHECK-NEXT: entry: 334; CHECK-NEXT: br label [[LOOP:%.*]] 335; CHECK: loop: 336; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ] 337; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ] 338; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ] 339; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 340; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX1]], align 8 341; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 342; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 343; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[P:%.*]] 344; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARRAYIDX_I]], align 8 345; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[P]] 346; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX1_I]], align 8 347; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i64 [[TMP2]], [[TMP3]] 348; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 349; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE:%.*]] 350; CHECK: select.false.sink: 351; CHECK-NEXT: [[TMP5:%.*]] = add nsw i64 [[J]], -1 352; CHECK-NEXT: br label [[SELECT_END1]] 353; CHECK: select.end: 354; CHECK-NEXT: [[DOTSINK:%.*]] = phi ptr [ [[TMP0]], [[LOOP]] ], [ [[TMP1]], [[SELECT_FALSE]] ] 355; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP5]], [[SELECT_FALSE]] ] 356; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 357; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64 358; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 359; CHECK-NEXT: store ptr [[DOTSINK]], ptr [[TMP4]], align 8 360; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 361; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 362; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 363; CHECK: exit: 364; CHECK-NEXT: ret void 365; 366entry: 367 br label %loop 368 369loop: 370 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 371 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 372 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 373 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 374 %l.gep.i = load ptr, ptr %gep.i, align 8 375 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 376 %l.gep.j = load ptr, ptr %gep.j, align 8 377 %gep.i.1 = getelementptr inbounds i64, ptr %l.gep.i, i64 %p 378 %2 = load i64, ptr %gep.i.1, align 8 379 %gep.j.1 = getelementptr inbounds i64, ptr %l.gep.j, i64 %p 380 %3 = load i64, ptr %gep.j.1, align 8 381 %cmp3 = icmp slt i64 %2, %3 382 %sel = select i1 %cmp3, ptr %l.gep.i, ptr %l.gep.j 383 %not.cmp3 = xor i1 %cmp3, true 384 %dec = sext i1 %not.cmp3 to i64 385 %j.next = add nsw i64 %j, %dec 386 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 387 store ptr %sel, ptr %gep.dst, align 8 388 %iv.next = add i64 %iv, 1 389 %ec = icmp eq i64 %iv, %j.start 390 br i1 %ec, label %exit, label %loop 391 392exit: 393 ret void 394} 395 396define void @test_sub_zext(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 397; CHECK-LABEL: @test_sub_zext( 398; CHECK-NEXT: entry: 399; CHECK-NEXT: br label [[LOOP:%.*]] 400; CHECK: loop: 401; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 402; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 403; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 404; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 405; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 406; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 407; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 408; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 409; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i64 410; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 411; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]] 412; CHECK: select.true.sink: 413; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], 1 414; CHECK-NEXT: br label [[SELECT_END]] 415; CHECK: select.end: 416; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ] 417; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 418; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 419; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 420; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 421; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 422; CHECK: exit: 423; CHECK-NEXT: ret void 424; 425entry: 426 br label %loop 427 428loop: 429 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 430 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 431 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 432 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 433 %l.i = load ptr, ptr %gep.i, align 8 434 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 435 %l.j = load ptr, ptr %gep.j, align 8 436 %cmp3 = icmp ult ptr %l.i, %l.j 437 %dec = zext i1 %cmp3 to i64 438 %j.next = sub nsw i64 %j, %dec 439 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 440 store i64 %j.next, ptr %gep.dst, align 8 441 %iv.next = add i64 %iv, 1 442 %ec = icmp eq i64 %iv, %j.start 443 br i1 %ec, label %exit, label %loop 444 445exit: 446 ret void 447} 448 449define void @test_sub_zext_first_op(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 450; CHECK-LABEL: @test_sub_zext_first_op( 451; CHECK-NEXT: entry: 452; CHECK-NEXT: br label [[LOOP:%.*]] 453; CHECK: loop: 454; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 455; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_START:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ] 456; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ] 457; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 458; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_DST]], align 8 459; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 [[J]] 460; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 461; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 462; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i64 463; CHECK-NEXT: [[J_NEXT]] = sub nsw i64 [[DEC]], [[J]] 464; CHECK-NEXT: [[GEP_DST1:%.*]] = getelementptr inbounds ptr, ptr [[DST1:%.*]], i64 [[IV1]] 465; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST1]], align 8 466; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 1 467; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV1]], [[J_START]] 468; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 469; CHECK: exit: 470; CHECK-NEXT: ret void 471; 472entry: 473 br label %loop 474 475loop: 476 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 477 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 478 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 479 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 480 %l.i = load ptr, ptr %gep.i, align 8 481 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 482 %l.j = load ptr, ptr %gep.j, align 8 483 %cmp3 = icmp ult ptr %l.i, %l.j 484 %dec = zext i1 %cmp3 to i64 485 %j.next = sub nsw i64 %dec, %j 486 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 487 store i64 %j.next, ptr %gep.dst, align 8 488 %iv.next = add i64 %iv, 1 489 %ec = icmp eq i64 %iv, %j.start 490 br i1 %ec, label %exit, label %loop 491 492exit: 493 ret void 494} 495 496define void @test_sub_zext_not(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 497; CHECK-LABEL: @test_sub_zext_not( 498; CHECK-NEXT: entry: 499; CHECK-NEXT: br label [[LOOP:%.*]] 500; CHECK: loop: 501; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 502; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_START:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 503; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 504; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 505; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 506; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 507; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 508; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 509; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 510; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[NOT_CMP3]] to i64 511; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 512; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE_SINK:%.*]] 513; CHECK: select.false.sink: 514; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], 1 515; CHECK-NEXT: br label [[SELECT_END]] 516; CHECK: select.end: 517; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE_SINK]] ] 518; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 519; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 520; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 521; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[J_START]] 522; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 523; CHECK: exit: 524; CHECK-NEXT: ret void 525; 526entry: 527 br label %loop 528 529loop: 530 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 531 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 532 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 533 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 534 %l.i = load ptr, ptr %gep.i, align 8 535 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 536 %l.j = load ptr, ptr %gep.j, align 8 537 %cmp3 = icmp ult ptr %l.i, %l.j 538 %not.cmp3 = xor i1 %cmp3, true 539 %dec = zext i1 %not.cmp3 to i64 540 %j.next = sub nsw i64 %j, %dec 541 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 542 store i64 %j.next, ptr %gep.dst, align 8 543 %iv.next = add i64 %iv, 1 544 %ec = icmp eq i64 %iv, %j.start 545 br i1 %ec, label %exit, label %loop 546 547exit: 548 ret void 549} 550 551define void @test_sub_sext(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 552; CHECK-LABEL: @test_sub_sext( 553; CHECK-NEXT: entry: 554; CHECK-NEXT: br label [[LOOP:%.*]] 555; CHECK: loop: 556; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 557; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 558; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 559; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 560; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 561; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 562; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 563; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 564; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[CMP3]] to i64 565; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 566; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]] 567; CHECK: select.true.sink: 568; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], -1 569; CHECK-NEXT: br label [[SELECT_END]] 570; CHECK: select.end: 571; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ] 572; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 573; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 574; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 575; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 576; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 577; CHECK: exit: 578; CHECK-NEXT: ret void 579; 580entry: 581 br label %loop 582 583loop: 584 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 585 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 586 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 587 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 588 %l.i = load ptr, ptr %gep.i, align 8 589 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 590 %l.j = load ptr, ptr %gep.j, align 8 591 %cmp3 = icmp ult ptr %l.i, %l.j 592 %dec = sext i1 %cmp3 to i64 593 %j.next = sub nsw i64 %j, %dec 594 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 595 store i64 %j.next, ptr %gep.dst, align 8 596 %iv.next = add i64 %iv, 1 597 %ec = icmp eq i64 %iv, %j.start 598 br i1 %ec, label %exit, label %loop 599 600exit: 601 ret void 602} 603 604define void @test_sub_sext_not(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 605; CHECK-LABEL: @test_sub_sext_not( 606; CHECK-NEXT: entry: 607; CHECK-NEXT: br label [[LOOP:%.*]] 608; CHECK: loop: 609; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 610; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 611; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ] 612; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 613; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 614; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 615; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 616; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 617; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 618; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64 619; CHECK-NEXT: [[NOT_CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 620; CHECK-NEXT: br i1 [[NOT_CMP3_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]] 621; CHECK: select.false.sink: 622; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], -1 623; CHECK-NEXT: br label [[SELECT_END]] 624; CHECK: select.end: 625; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE]] ] 626; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 627; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8 628; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 629; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 630; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 631; CHECK: exit: 632; CHECK-NEXT: ret void 633; 634entry: 635 br label %loop 636 637loop: 638 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 639 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 640 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 641 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 642 %l.i = load ptr, ptr %gep.i, align 8 643 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 644 %l.j = load ptr, ptr %gep.j, align 8 645 %cmp3 = icmp ult ptr %l.i, %l.j 646 %not.cmp3 = xor i1 %cmp3, true 647 %dec = sext i1 %not.cmp3 to i64 648 %j.next = sub nsw i64 %j, %dec 649 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 650 store i64 %j.next, ptr %gep.dst, align 8 651 %iv.next = add i64 %iv, 1 652 %ec = icmp eq i64 %iv, %j.start 653 br i1 %ec, label %exit, label %loop 654 655exit: 656 ret void 657} 658 659define void @test_sub_sext_not_and_regular_select(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 660; CHECK-LABEL: @test_sub_sext_not_and_regular_select( 661; CHECK-NEXT: entry: 662; CHECK-NEXT: br label [[LOOP:%.*]] 663; CHECK: loop: 664; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ] 665; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ] 666; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ] 667; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 668; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8 669; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 670; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8 671; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]] 672; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 673; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64 674; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 675; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE_SINK:%.*]] 676; CHECK: select.false.sink: 677; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], -1 678; CHECK-NEXT: br label [[SELECT_END1]] 679; CHECK: select.end: 680; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE_SINK]] ] 681; CHECK-NEXT: [[SINK:%.*]] = phi ptr [ [[L_I]], [[LOOP]] ], [ [[L_J]], [[SELECT_FALSE_SINK]] ] 682; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 683; CHECK-NEXT: store ptr [[SINK]], ptr [[GEP_DST]], align 8 684; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 685; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 686; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 687; CHECK: exit: 688; CHECK-NEXT: ret void 689; 690entry: 691 br label %loop 692 693loop: 694 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 695 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 696 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 697 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 698 %l.i = load ptr, ptr %gep.i, align 8 699 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 700 %l.j = load ptr, ptr %gep.j, align 8 701 %cmp3 = icmp ult ptr %l.i, %l.j 702 %not.cmp3 = xor i1 %cmp3, true 703 %dec = sext i1 %not.cmp3 to i64 704 %j.next = sub nsw i64 %j, %dec 705 %sink = select i1 %cmp3, ptr %l.i, ptr %l.j 706 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 707 store ptr %sink, ptr %gep.dst, align 8 708 %iv.next = add i64 %iv, 1 709 %ec = icmp eq i64 %iv, %j.start 710 br i1 %ec, label %exit, label %loop 711 712exit: 713 ret void 714} 715 716define void @test_sub_sext_not_and_regular_select2(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.start) { 717; CHECK-LABEL: @test_sub_sext_not_and_regular_select2( 718; CHECK-NEXT: entry: 719; CHECK-NEXT: br label [[LOOP:%.*]] 720; CHECK: loop: 721; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ] 722; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ] 723; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ] 724; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 725; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX1]], align 8 726; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]] 727; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 728; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[P:%.*]] 729; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARRAYIDX_I]], align 8 730; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[P]] 731; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX1_I]], align 8 732; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i64 [[TMP2]], [[TMP3]] 733; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]] 734; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE:%.*]] 735; CHECK: select.false.sink: 736; CHECK-NEXT: [[TMP5:%.*]] = sub nsw i64 [[J]], -1 737; CHECK-NEXT: br label [[SELECT_END1]] 738; CHECK: select.end: 739; CHECK-NEXT: [[DOTSINK:%.*]] = phi ptr [ [[TMP0]], [[LOOP]] ], [ [[TMP1]], [[SELECT_FALSE]] ] 740; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP5]], [[SELECT_FALSE]] ] 741; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true 742; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64 743; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]] 744; CHECK-NEXT: store ptr [[DOTSINK]], ptr [[TMP4]], align 8 745; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 746; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[HIGH]] 747; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP]] 748; CHECK: exit: 749; CHECK-NEXT: ret void 750; 751entry: 752 br label %loop 753 754loop: 755 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 756 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 757 %i = phi i64 [ %i.start, %entry ], [ %j.next, %loop ] 758 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 759 %l.gep.i = load ptr, ptr %gep.i, align 8 760 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j 761 %l.gep.j = load ptr, ptr %gep.j, align 8 762 %gep.i.1 = getelementptr inbounds i64, ptr %l.gep.i, i64 %p 763 %2 = load i64, ptr %gep.i.1, align 8 764 %gep.j.1 = getelementptr inbounds i64, ptr %l.gep.j, i64 %p 765 %3 = load i64, ptr %gep.j.1, align 8 766 %cmp3 = icmp slt i64 %2, %3 767 %sel = select i1 %cmp3, ptr %l.gep.i, ptr %l.gep.j 768 %not.cmp3 = xor i1 %cmp3, true 769 %dec = sext i1 %not.cmp3 to i64 770 %j.next = sub nsw i64 %j, %dec 771 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv 772 store ptr %sel, ptr %gep.dst, align 8 773 %iv.next = add i64 %iv, 1 774 %ec = icmp eq i64 %iv, %j.start 775 br i1 %ec, label %exit, label %loop 776 777exit: 778 ret void 779} 780 781define void @test_add_lshr_add_regular_select(ptr %dst, ptr %src, i64 %i.start, i64 %j.start) { 782; CHECK-LABEL: @test_add_lshr_add_regular_select( 783; CHECK-NEXT: entry: 784; CHECK-NEXT: br label [[LOOP:%.*]] 785; CHECK: loop: 786; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 100000, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 787; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[I_NEXT:%.*]], [[SELECT_END]] ] 788; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_START:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 789; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 790; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GEP_I]], align 8 791; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[J]] 792; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[GEP_J]], align 8 793; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], -1 794; CHECK-NEXT: [[SHIFT:%.*]] = lshr i64 [[TMP1]], 63 795; CHECK-NEXT: [[CMP_FROZEN:%.*]] = freeze i1 [[CMP]] 796; CHECK-NEXT: br i1 [[CMP_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_FALSE_SINK:%.*]] 797; CHECK: select.true.sink: 798; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[I]], 1 799; CHECK-NEXT: br label [[SELECT_END]] 800; CHECK: select.false.sink: 801; CHECK-NEXT: [[TMP3:%.*]] = add nsw i64 [[J]], 1 802; CHECK-NEXT: br label [[SELECT_END]] 803; CHECK: select.end: 804; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[SELECT_TRUE_SINK]] ], [ [[TMP3]], [[SELECT_FALSE_SINK]] ] 805; CHECK-NEXT: [[I_NEXT]] = phi i64 [ [[TMP2]], [[SELECT_TRUE_SINK]] ], [ [[I]], [[SELECT_FALSE_SINK]] ] 806; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[J]], [[SELECT_TRUE_SINK]] ], [ [[I]], [[SELECT_FALSE_SINK]] ] 807; CHECK-NEXT: [[INC:%.*]] = zext i1 [[CMP]] to i64 808; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST:%.*]], i64 [[IV]] 809; CHECK-NEXT: store i64 [[COND]], ptr [[GEP_DST]], align 8 810; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], -1 811; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 0 812; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 813; CHECK: exit: 814; CHECK-NEXT: ret void 815; 816entry: 817 br label %loop 818 819loop: 820 %iv = phi i64 [ 100000, %entry ], [ %iv.next, %loop ] 821 %i = phi i64 [ %i.start, %entry ], [ %i.next, %loop ] 822 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 823 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 824 %0 = load ptr, ptr %gep.i, align 8 825 %gep.j = getelementptr inbounds i64, ptr %0, i64 %j 826 %1 = load i64, ptr %gep.j, align 8 827 %cmp = icmp sgt i64 %1, -1 828 %shift = lshr i64 %1, 63 829 %j.next = add nsw i64 %j, %shift 830 %inc = zext i1 %cmp to i64 831 %i.next = add nsw i64 %i, %inc 832 %cond = select i1 %cmp, i64 %j, i64 %i 833 %gep.dst = getelementptr i64, ptr %dst, i64 %iv 834 store i64 %cond, ptr %gep.dst, align 8 835 %iv.next = add nsw i64 %iv, -1 836 %ec = icmp eq i64 %iv.next, 0 837 br i1 %ec, label %exit, label %loop 838 839exit: 840 ret void 841} 842 843define void @test_add_ashr_add_regular_select(ptr %dst, ptr %src, i64 %i.start, i64 %j.start) { 844; CHECK-LABEL: @test_add_ashr_add_regular_select( 845; CHECK-NEXT: entry: 846; CHECK-NEXT: br label [[LOOP:%.*]] 847; CHECK: loop: 848; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 100000, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ] 849; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[I_NEXT:%.*]], [[SELECT_END]] ] 850; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_START:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ] 851; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]] 852; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GEP_I]], align 8 853; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[J]] 854; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[GEP_J]], align 8 855; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], -1 856; CHECK-NEXT: [[SHIFT:%.*]] = ashr i64 [[TMP1]], 63 857; CHECK-NEXT: [[CMP_FROZEN:%.*]] = freeze i1 [[CMP]] 858; CHECK-NEXT: br i1 [[CMP_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_FALSE_SINK:%.*]] 859; CHECK: select.true.sink: 860; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[I]], 1 861; CHECK-NEXT: br label [[SELECT_END]] 862; CHECK: select.false.sink: 863; CHECK-NEXT: [[TMP3:%.*]] = add nsw i64 [[J]], -1 864; CHECK-NEXT: br label [[SELECT_END]] 865; CHECK: select.end: 866; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[SELECT_TRUE_SINK]] ], [ [[TMP3]], [[SELECT_FALSE_SINK]] ] 867; CHECK-NEXT: [[I_NEXT]] = phi i64 [ [[TMP2]], [[SELECT_TRUE_SINK]] ], [ [[I]], [[SELECT_FALSE_SINK]] ] 868; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[J]], [[SELECT_TRUE_SINK]] ], [ [[I]], [[SELECT_FALSE_SINK]] ] 869; CHECK-NEXT: [[INC:%.*]] = zext i1 [[CMP]] to i64 870; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST:%.*]], i64 [[IV]] 871; CHECK-NEXT: store i64 [[COND]], ptr [[GEP_DST]], align 8 872; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], -1 873; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 0 874; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 875; CHECK: exit: 876; CHECK-NEXT: ret void 877; 878entry: 879 br label %loop 880 881loop: 882 %iv = phi i64 [ 100000, %entry ], [ %iv.next, %loop ] 883 %i = phi i64 [ %i.start, %entry ], [ %i.next, %loop ] 884 %j = phi i64 [ %j.start, %entry ], [ %j.next, %loop ] 885 %gep.i = getelementptr inbounds ptr, ptr %src, i64 %i 886 %0 = load ptr, ptr %gep.i, align 8 887 %gep.j = getelementptr inbounds i64, ptr %0, i64 %j 888 %1 = load i64, ptr %gep.j, align 8 889 %cmp = icmp sgt i64 %1, -1 890 %shift = ashr i64 %1, 63 891 %j.next = add nsw i64 %j, %shift 892 %inc = zext i1 %cmp to i64 893 %i.next = add nsw i64 %i, %inc 894 %cond = select i1 %cmp, i64 %j, i64 %i 895 %gep.dst = getelementptr i64, ptr %dst, i64 %iv 896 store i64 %cond, ptr %gep.dst, align 8 897 %iv.next = add nsw i64 %iv, -1 898 %ec = icmp eq i64 %iv.next, 0 899 br i1 %ec, label %exit, label %loop 900 901exit: 902 ret void 903} 904