904 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -select-optimize -mtriple=arm64-apple-macosx -S %s | FileCheck %s3; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=arm64-apple-macosx -S %s | FileCheck %s4 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 815; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]16; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 817; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]18; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i6419; 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]], 123; 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 828; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 129; 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 void33;34entry:35 br label %loop36 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 %i42 %l.i = load ptr, ptr %gep.i, align 843 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j44 %l.j = load ptr, ptr %gep.j, align 845 %cmp3 = icmp ult ptr %l.i, %l.j46 %dec = zext i1 %cmp3 to i6447 %j.next = add nsw i64 %j, %dec48 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv49 store i64 %j.next, ptr %gep.dst, align 850 %iv.next = add i64 %iv, 151 %ec = icmp eq i64 %iv, %j.start52 br i1 %ec, label %exit, label %loop53 54exit:55 ret void56}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 868; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 [[J]]69; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 870; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]71; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i6472; 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 881; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 182; 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 void86;87entry:88 br label %loop89 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 %i95 %l.i = load ptr, ptr %gep.i, align 896 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j97 %l.j = load ptr, ptr %gep.j, align 898 %cmp3 = icmp ult ptr %l.i, %l.j99 %dec = zext i1 %cmp3 to i64100 %j.next = add nsw i64 %dec, %j101 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv102 store i64 %j.next, ptr %gep.dst, align 8103 %iv.next = add i64 %iv, 1104 %ec = icmp eq i64 %iv, %j.start105 br i1 %ec, label %exit, label %loop106 107exit:108 ret void109}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 8121; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]122; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8123; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]124; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true125; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[NOT_CMP3]] to i64126; 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]], 1130; 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 8135; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1136; 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 void140;141entry:142 br label %loop143 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 %i149 %l.i = load ptr, ptr %gep.i, align 8150 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j151 %l.j = load ptr, ptr %gep.j, align 8152 %cmp3 = icmp ult ptr %l.i, %l.j153 %not.cmp3 = xor i1 %cmp3, true154 %dec = zext i1 %not.cmp3 to i64155 %j.next = add nsw i64 %j, %dec156 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv157 store i64 %j.next, ptr %gep.dst, align 8158 %iv.next = add i64 %iv, 1159 %ec = icmp eq i64 %iv, %j.start160 br i1 %ec, label %exit, label %loop161 162exit:163 ret void164}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 8176; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]177; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8178; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]179; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[CMP3]] to i64180; 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]], -1184; 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 8189; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1190; 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 void194;195entry:196 br label %loop197 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 %i203 %l.i = load ptr, ptr %gep.i, align 8204 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j205 %l.j = load ptr, ptr %gep.j, align 8206 %cmp3 = icmp ult ptr %l.i, %l.j207 %dec = sext i1 %cmp3 to i64208 %j.next = add nsw i64 %j, %dec209 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv210 store i64 %j.next, ptr %gep.dst, align 8211 %iv.next = add i64 %iv, 1212 %ec = icmp eq i64 %iv, %j.start213 br i1 %ec, label %exit, label %loop214 215exit:216 ret void217}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 8229; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]230; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8231; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]232; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true233; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64234; 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]], -1238; 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 8243; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1244; 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 void248;249entry:250 br label %loop251 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 %i257 %l.i = load ptr, ptr %gep.i, align 8258 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j259 %l.j = load ptr, ptr %gep.j, align 8260 %cmp3 = icmp ult ptr %l.i, %l.j261 %not.cmp3 = xor i1 %cmp3, true262 %dec = sext i1 %not.cmp3 to i64263 %j.next = add nsw i64 %j, %dec264 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv265 store i64 %j.next, ptr %gep.dst, align 8266 %iv.next = add i64 %iv, 1267 %ec = icmp eq i64 %iv, %j.start268 br i1 %ec, label %exit, label %loop269 270exit:271 ret void272}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 8284; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]285; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8286; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]287; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true288; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64289; 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]], -1293; 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 8299; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1300; 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 void304;305entry:306 br label %loop307 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 %i313 %l.i = load ptr, ptr %gep.i, align 8314 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j315 %l.j = load ptr, ptr %gep.j, align 8316 %cmp3 = icmp ult ptr %l.i, %l.j317 %not.cmp3 = xor i1 %cmp3, true318 %dec = sext i1 %not.cmp3 to i64319 %j.next = add nsw i64 %j, %dec320 %sink = select i1 %cmp3, ptr %l.i, ptr %l.j321 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv322 store ptr %sink, ptr %gep.dst, align 8323 %iv.next = add i64 %iv, 1324 %ec = icmp eq i64 %iv, %j.start325 br i1 %ec, label %exit, label %loop326 327exit:328 ret void329}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 8341; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]342; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8343; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[P:%.*]]344; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARRAYIDX_I]], align 8345; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[P]]346; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX1_I]], align 8347; 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]], -1352; 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]], true357; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64358; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]359; CHECK-NEXT: store ptr [[DOTSINK]], ptr [[TMP4]], align 8360; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1361; 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 void365;366entry:367 br label %loop368 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 %i374 %l.gep.i = load ptr, ptr %gep.i, align 8375 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j376 %l.gep.j = load ptr, ptr %gep.j, align 8377 %gep.i.1 = getelementptr inbounds i64, ptr %l.gep.i, i64 %p378 %2 = load i64, ptr %gep.i.1, align 8379 %gep.j.1 = getelementptr inbounds i64, ptr %l.gep.j, i64 %p380 %3 = load i64, ptr %gep.j.1, align 8381 %cmp3 = icmp slt i64 %2, %3382 %sel = select i1 %cmp3, ptr %l.gep.i, ptr %l.gep.j383 %not.cmp3 = xor i1 %cmp3, true384 %dec = sext i1 %not.cmp3 to i64385 %j.next = add nsw i64 %j, %dec386 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv387 store ptr %sel, ptr %gep.dst, align 8388 %iv.next = add i64 %iv, 1389 %ec = icmp eq i64 %iv, %j.start390 br i1 %ec, label %exit, label %loop391 392exit:393 ret void394}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 8406; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]407; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8408; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]409; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i64410; 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]], 1414; 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 8419; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1420; 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 void424;425entry:426 br label %loop427 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 %i433 %l.i = load ptr, ptr %gep.i, align 8434 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j435 %l.j = load ptr, ptr %gep.j, align 8436 %cmp3 = icmp ult ptr %l.i, %l.j437 %dec = zext i1 %cmp3 to i64438 %j.next = sub nsw i64 %j, %dec439 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv440 store i64 %j.next, ptr %gep.dst, align 8441 %iv.next = add i64 %iv, 1442 %ec = icmp eq i64 %iv, %j.start443 br i1 %ec, label %exit, label %loop444 445exit:446 ret void447}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 8459; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 [[J]]460; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8461; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]462; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[CMP3]] to i64463; 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 8466; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 1467; 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 void471;472entry:473 br label %loop474 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 %i480 %l.i = load ptr, ptr %gep.i, align 8481 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j482 %l.j = load ptr, ptr %gep.j, align 8483 %cmp3 = icmp ult ptr %l.i, %l.j484 %dec = zext i1 %cmp3 to i64485 %j.next = sub nsw i64 %dec, %j486 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv487 store i64 %j.next, ptr %gep.dst, align 8488 %iv.next = add i64 %iv, 1489 %ec = icmp eq i64 %iv, %j.start490 br i1 %ec, label %exit, label %loop491 492exit:493 ret void494}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 8506; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]507; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8508; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]509; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true510; CHECK-NEXT: [[DEC:%.*]] = zext i1 [[NOT_CMP3]] to i64511; 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]], 1515; 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 8520; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1521; 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 void525;526entry:527 br label %loop528 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 %i534 %l.i = load ptr, ptr %gep.i, align 8535 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j536 %l.j = load ptr, ptr %gep.j, align 8537 %cmp3 = icmp ult ptr %l.i, %l.j538 %not.cmp3 = xor i1 %cmp3, true539 %dec = zext i1 %not.cmp3 to i64540 %j.next = sub nsw i64 %j, %dec541 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv542 store i64 %j.next, ptr %gep.dst, align 8543 %iv.next = add i64 %iv, 1544 %ec = icmp eq i64 %iv, %j.start545 br i1 %ec, label %exit, label %loop546 547exit:548 ret void549}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 8561; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]562; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8563; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]564; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[CMP3]] to i64565; 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]], -1569; 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 8574; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1575; 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 void579;580entry:581 br label %loop582 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 %i588 %l.i = load ptr, ptr %gep.i, align 8589 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j590 %l.j = load ptr, ptr %gep.j, align 8591 %cmp3 = icmp ult ptr %l.i, %l.j592 %dec = sext i1 %cmp3 to i64593 %j.next = sub nsw i64 %j, %dec594 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv595 store i64 %j.next, ptr %gep.dst, align 8596 %iv.next = add i64 %iv, 1597 %ec = icmp eq i64 %iv, %j.start598 br i1 %ec, label %exit, label %loop599 600exit:601 ret void602}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 8614; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]615; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8616; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]617; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true618; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64619; 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]], -1623; 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 8628; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1629; 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 void633;634entry:635 br label %loop636 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 %i642 %l.i = load ptr, ptr %gep.i, align 8643 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j644 %l.j = load ptr, ptr %gep.j, align 8645 %cmp3 = icmp ult ptr %l.i, %l.j646 %not.cmp3 = xor i1 %cmp3, true647 %dec = sext i1 %not.cmp3 to i64648 %j.next = sub nsw i64 %j, %dec649 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv650 store i64 %j.next, ptr %gep.dst, align 8651 %iv.next = add i64 %iv, 1652 %ec = icmp eq i64 %iv, %j.start653 br i1 %ec, label %exit, label %loop654 655exit:656 ret void657}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 8669; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]670; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8671; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]672; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true673; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64674; 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]], -1678; 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 8684; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1685; 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 void689;690entry:691 br label %loop692 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 %i698 %l.i = load ptr, ptr %gep.i, align 8699 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j700 %l.j = load ptr, ptr %gep.j, align 8701 %cmp3 = icmp ult ptr %l.i, %l.j702 %not.cmp3 = xor i1 %cmp3, true703 %dec = sext i1 %not.cmp3 to i64704 %j.next = sub nsw i64 %j, %dec705 %sink = select i1 %cmp3, ptr %l.i, ptr %l.j706 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv707 store ptr %sink, ptr %gep.dst, align 8708 %iv.next = add i64 %iv, 1709 %ec = icmp eq i64 %iv, %j.start710 br i1 %ec, label %exit, label %loop711 712exit:713 ret void714}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 8726; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]727; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8728; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[P:%.*]]729; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARRAYIDX_I]], align 8730; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[P]]731; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX1_I]], align 8732; 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]], -1737; 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]], true742; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64743; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]744; CHECK-NEXT: store ptr [[DOTSINK]], ptr [[TMP4]], align 8745; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1746; 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 void750;751entry:752 br label %loop753 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 %i759 %l.gep.i = load ptr, ptr %gep.i, align 8760 %gep.j = getelementptr inbounds ptr, ptr %src, i64 %j761 %l.gep.j = load ptr, ptr %gep.j, align 8762 %gep.i.1 = getelementptr inbounds i64, ptr %l.gep.i, i64 %p763 %2 = load i64, ptr %gep.i.1, align 8764 %gep.j.1 = getelementptr inbounds i64, ptr %l.gep.j, i64 %p765 %3 = load i64, ptr %gep.j.1, align 8766 %cmp3 = icmp slt i64 %2, %3767 %sel = select i1 %cmp3, ptr %l.gep.i, ptr %l.gep.j768 %not.cmp3 = xor i1 %cmp3, true769 %dec = sext i1 %not.cmp3 to i64770 %j.next = sub nsw i64 %j, %dec771 %gep.dst = getelementptr inbounds ptr, ptr %dst, i64 %iv772 store ptr %sel, ptr %gep.dst, align 8773 %iv.next = add i64 %iv, 1774 %ec = icmp eq i64 %iv, %j.start775 br i1 %ec, label %exit, label %loop776 777exit:778 ret void779}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 8791; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[J]]792; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[GEP_J]], align 8793; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], -1794; CHECK-NEXT: [[SHIFT:%.*]] = lshr i64 [[TMP1]], 63795; 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]], 1799; CHECK-NEXT: br label [[SELECT_END]]800; CHECK: select.false.sink:801; CHECK-NEXT: [[TMP3:%.*]] = add nsw i64 [[J]], 1802; 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 i64808; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST:%.*]], i64 [[IV]]809; CHECK-NEXT: store i64 [[COND]], ptr [[GEP_DST]], align 8810; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], -1811; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 0812; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]813; CHECK: exit:814; CHECK-NEXT: ret void815;816entry:817 br label %loop818 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 %i824 %0 = load ptr, ptr %gep.i, align 8825 %gep.j = getelementptr inbounds i64, ptr %0, i64 %j826 %1 = load i64, ptr %gep.j, align 8827 %cmp = icmp sgt i64 %1, -1828 %shift = lshr i64 %1, 63829 %j.next = add nsw i64 %j, %shift830 %inc = zext i1 %cmp to i64831 %i.next = add nsw i64 %i, %inc832 %cond = select i1 %cmp, i64 %j, i64 %i833 %gep.dst = getelementptr i64, ptr %dst, i64 %iv834 store i64 %cond, ptr %gep.dst, align 8835 %iv.next = add nsw i64 %iv, -1836 %ec = icmp eq i64 %iv.next, 0837 br i1 %ec, label %exit, label %loop838 839exit:840 ret void841}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 8853; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds i64, ptr [[TMP0]], i64 [[J]]854; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[GEP_J]], align 8855; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], -1856; CHECK-NEXT: [[SHIFT:%.*]] = ashr i64 [[TMP1]], 63857; 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]], 1861; CHECK-NEXT: br label [[SELECT_END]]862; CHECK: select.false.sink:863; CHECK-NEXT: [[TMP3:%.*]] = add nsw i64 [[J]], -1864; 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 i64870; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST:%.*]], i64 [[IV]]871; CHECK-NEXT: store i64 [[COND]], ptr [[GEP_DST]], align 8872; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], -1873; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 0874; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]875; CHECK: exit:876; CHECK-NEXT: ret void877;878entry:879 br label %loop880 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 %i886 %0 = load ptr, ptr %gep.i, align 8887 %gep.j = getelementptr inbounds i64, ptr %0, i64 %j888 %1 = load i64, ptr %gep.j, align 8889 %cmp = icmp sgt i64 %1, -1890 %shift = ashr i64 %1, 63891 %j.next = add nsw i64 %j, %shift892 %inc = zext i1 %cmp to i64893 %i.next = add nsw i64 %i, %inc894 %cond = select i1 %cmp, i64 %j, i64 %i895 %gep.dst = getelementptr i64, ptr %dst, i64 %iv896 store i64 %cond, ptr %gep.dst, align 8897 %iv.next = add nsw i64 %iv, -1898 %ec = icmp eq i64 %iv.next, 0899 br i1 %ec, label %exit, label %loop900 901exit:902 ret void903}904