1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define void @f(i64 %val, i32 %limit, ptr %ptr) { 5; CHECK-LABEL: @f( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[VAL:%.*]] to i32 8; CHECK-NEXT: br label [[LOOP:%.*]] 9; CHECK: loop: 10; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[LOOP]] ] 11; CHECK-NEXT: [[END:%.*]] = icmp ult i32 [[TMP1]], [[LIMIT:%.*]] 12; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 10 13; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64 14; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 [[TMP3]] 15; CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP4]], align 4 16; CHECK-NEXT: [[TMP5]] = add i32 [[TMP1]], 16 17; CHECK-NEXT: br i1 [[END]], label [[LOOP]], label [[RET:%.*]] 18; CHECK: ret: 19; CHECK-NEXT: ret void 20; 21entry: 22 %tempvector = insertelement <16 x i64> poison, i64 %val, i32 0 23 %vector = shufflevector <16 x i64> %tempvector, <16 x i64> poison, <16 x i32> zeroinitializer 24 %0 = add <16 x i64> %vector, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15> 25 %1 = trunc <16 x i64> %0 to <16 x i32> 26 br label %loop 27 28loop: 29 %2 = phi <16 x i32> [ %1, %entry ], [ %inc, %loop ] 30 %elt = extractelement <16 x i32> %2, i32 0 31 %end = icmp ult i32 %elt, %limit 32 %3 = add i32 10, %elt 33 %4 = sext i32 %elt to i64 34 %5 = getelementptr i32, ptr %ptr, i64 %4 35 store i32 %3, ptr %5 36 %inc = add <16 x i32> %2, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 37 br i1 %end, label %loop, label %ret 38 39ret: 40 ret void 41} 42 43define void @copy(i64 %val, i32 %limit, ptr %ptr) { 44; CHECK-LABEL: @copy( 45; CHECK-NEXT: entry: 46; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[VAL:%.*]] to i32 47; CHECK-NEXT: br label [[LOOP:%.*]] 48; CHECK: loop: 49; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[LOOP]] ] 50; CHECK-NEXT: [[END:%.*]] = icmp ult i32 [[TMP1]], [[LIMIT:%.*]] 51; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 10 52; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64 53; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 [[TMP3]] 54; CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP4]], align 4 55; CHECK-NEXT: [[TMP5]] = add i32 [[TMP1]], 16 56; CHECK-NEXT: br i1 [[END]], label [[LOOP]], label [[RET:%.*]] 57; CHECK: ret: 58; CHECK-NEXT: ret void 59; 60entry: 61 %tempvector = insertelement <16 x i64> poison, i64 %val, i32 0 62 %vector = shufflevector <16 x i64> %tempvector, <16 x i64> poison, <16 x i32> zeroinitializer 63 %0 = add <16 x i64> %vector, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15> 64 %1 = trunc <16 x i64> %0 to <16 x i32> 65 br label %loop 66 67loop: 68 %2 = phi <16 x i32> [ %1, %entry ], [ %inc, %loop ] 69 %elt = extractelement <16 x i32> %2, i32 0 70 %eltcopy = extractelement <16 x i32> %2, i32 0 71 %end = icmp ult i32 %elt, %limit 72 %3 = add i32 10, %eltcopy 73 %4 = sext i32 %elt to i64 74 %5 = getelementptr i32, ptr %ptr, i64 %4 75 store i32 %3, ptr %5 76 %inc = add <16 x i32> %2, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 77 br i1 %end, label %loop, label %ret 78 79ret: 80 ret void 81} 82 83define void @nocopy(i64 %val, i32 %limit, ptr %ptr) { 84; CHECK-LABEL: @nocopy( 85; CHECK-NEXT: entry: 86; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[VAL:%.*]] to i32 87; CHECK-NEXT: [[TMP1:%.*]] = insertelement <16 x i32> poison, i32 [[TMP0]], i64 0 88; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i32> [[TMP1]], <16 x i32> poison, <16 x i32> zeroinitializer 89; CHECK-NEXT: [[TMP3:%.*]] = add <16 x i32> [[TMP2]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 90; CHECK-NEXT: br label [[LOOP:%.*]] 91; CHECK: loop: 92; CHECK-NEXT: [[TMP4:%.*]] = phi <16 x i32> [ [[TMP3]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] 93; CHECK-NEXT: [[ELT:%.*]] = extractelement <16 x i32> [[TMP4]], i64 0 94; CHECK-NEXT: [[ELTCOPY:%.*]] = extractelement <16 x i32> [[TMP4]], i64 1 95; CHECK-NEXT: [[END:%.*]] = icmp ult i32 [[ELT]], [[LIMIT:%.*]] 96; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[ELTCOPY]], 10 97; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[ELT]] to i64 98; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 [[TMP6]] 99; CHECK-NEXT: store i32 [[TMP5]], ptr [[TMP7]], align 4 100; CHECK-NEXT: [[INC]] = add <16 x i32> [[TMP4]], splat (i32 16) 101; CHECK-NEXT: br i1 [[END]], label [[LOOP]], label [[RET:%.*]] 102; CHECK: ret: 103; CHECK-NEXT: ret void 104; 105entry: 106 %tempvector = insertelement <16 x i64> poison, i64 %val, i32 0 107 %vector = shufflevector <16 x i64> %tempvector, <16 x i64> poison, <16 x i32> zeroinitializer 108 %0 = add <16 x i64> %vector, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15> 109 %1 = trunc <16 x i64> %0 to <16 x i32> 110 br label %loop 111 112loop: 113 %2 = phi <16 x i32> [ %1, %entry ], [ %inc, %loop ] 114 %elt = extractelement <16 x i32> %2, i32 0 115 %eltcopy = extractelement <16 x i32> %2, i32 1 116 %end = icmp ult i32 %elt, %limit 117 %3 = add i32 10, %eltcopy 118 %4 = sext i32 %elt to i64 119 %5 = getelementptr i32, ptr %ptr, i64 %4 120 store i32 %3, ptr %5 121 %inc = add <16 x i32> %2, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 122 br i1 %end, label %loop, label %ret 123 124ret: 125 ret void 126} 127 128define i1 @g(<3 x i32> %input_2, i1 %c1) { 129; CHECK-LABEL: @g( 130; CHECK-NEXT: entry: 131; CHECK-NEXT: [[TMP0:%.*]] = extractelement <3 x i32> [[INPUT_2:%.*]], i64 0 132; CHECK-NEXT: br label [[FOR_COND:%.*]] 133; CHECK: for.cond: 134; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP4:%.*]], [[FOR_BODY:%.*]] ] 135; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ poison, [[ENTRY]] ], [ [[TMP3:%.*]], [[FOR_BODY]] ] 136; CHECK-NEXT: br i1 [[C1:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY]] 137; CHECK: for.body: 138; CHECK-NEXT: [[TMP3]] = add i32 [[TMP2]], -1 139; CHECK-NEXT: [[SUB44_ELT:%.*]] = sub i32 0, [[TMP2]] 140; CHECK-NEXT: [[TMP4]] = sdiv i32 [[TMP1]], [[SUB44_ELT]] 141; CHECK-NEXT: br label [[FOR_COND]] 142; CHECK: for.end: 143; CHECK-NEXT: [[TOBOOL313:%.*]] = icmp eq i32 [[TMP1]], 0 144; CHECK-NEXT: ret i1 [[TOBOOL313]] 145; 146entry: 147 br label %for.cond 148 149for.cond: 150 %input_2.addr.0 = phi <3 x i32> [ %input_2, %entry ], [ %div45, %for.body ] 151 %input_1.addr.1 = phi <3 x i32> [ poison, %entry ], [ %dec43, %for.body ] 152 br i1 %c1, label %for.end, label %for.body 153 154for.body: 155 %dec43 = add <3 x i32> %input_1.addr.1, <i32 -1, i32 -1, i32 -1> 156 %sub44 = sub <3 x i32> <i32 -1, i32 -1, i32 -1>, %dec43 157 %div45 = sdiv <3 x i32> %input_2.addr.0, %sub44 158 br label %for.cond 159 160for.end: 161 %0 = extractelement <3 x i32> %input_2.addr.0, i32 0 162 %.89 = select i1 false, i32 0, i32 %0 163 %tobool313 = icmp eq i32 %.89, 0 164 ret i1 %tobool313 165} 166 167