1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -indvars -S | FileCheck %s 3 4@array = dso_local global [16777219 x i32] zeroinitializer, align 4 5 6define void @small_const_bound(i32 %index) { 7; CHECK-LABEL: @small_const_bound( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[FOR_BODY:%.*]] 10; CHECK: for.body: 11; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[DEC_INT:%.*]], [[FOR_BODY]] ] 12; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[IV_INT]] to i64 13; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 [[IDXPROM]] 14; CHECK-NEXT: store i32 [[IV_INT]], i32* [[ARRAYIDX]], align 4 15; CHECK-NEXT: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 16; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 0 17; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP:%.*]] 18; CHECK: cleanup: 19; CHECK-NEXT: ret void 20; 21entry: 22 br label %for.body 23 24for.body: ; preds = %for.body, %entry 25 %iv.int = phi i32 [ 100, %entry ], [ %dec.int, %for.body ] 26 %indvar.conv = sitofp i32 %iv.int to float 27 %conv = fptosi float %indvar.conv to i32 28 %idxprom = sext i32 %conv to i64 29 %arrayidx = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 %idxprom 30 store i32 %conv, i32* %arrayidx, align 4 31 %dec.int = add nsw i32 %iv.int, -1 32 %cmp = icmp ugt i32 %dec.int, 0 33 br i1 %cmp, label %for.body, label %cleanup 34 35cleanup: ; preds = %for.body 36 ret void 37} 38 39; Negative test: The transform is *not* valid because there are too many significant bits 40define void @overflow_masked_const_bound(i32 %index) { 41; CHECK-LABEL: @overflow_masked_const_bound( 42; CHECK-NEXT: entry: 43; CHECK-NEXT: br label [[FOR_BODY:%.*]] 44; CHECK: for.body: 45; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 16777218, [[ENTRY:%.*]] ], [ [[DEC_INT:%.*]], [[FOR_BODY]] ] 46; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to float 47; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[INDVAR_CONV]] to i32 48; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[CONV]] to i64 49; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 [[IDXPROM]] 50; CHECK-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4 51; CHECK-NEXT: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 52; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 0 53; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP:%.*]] 54; CHECK: cleanup: 55; CHECK-NEXT: ret void 56; 57entry: 58 br label %for.body 59 60for.body: ; preds = %for.body, %entry 61 %iv.int = phi i32 [ 16777218, %entry ], [ %dec.int, %for.body ] ; intermediate 16777218 (= 1 << 24 + 2) 62 %indvar.conv = sitofp i32 %iv.int to float 63 %conv = fptosi float %indvar.conv to i32 64 %idxprom = sext i32 %conv to i64 65 %arrayidx = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 %idxprom 66 store i32 %conv, i32* %arrayidx, align 4 67 %dec.int = add nsw i32 %iv.int, -1 68 %cmp = icmp ugt i32 %dec.int, 0 69 br i1 %cmp, label %for.body, label %cleanup 70 71cleanup: ; preds = %for.body 72 ret void 73} 74 75; Negative test: Type mismatch between the integer IV and the fptosi result 76define void @mismatch_type_const(i32 %index) { 77; 78; CHECK-LABEL: @mismatch_type_const( 79; CHECK-NEXT: entry: 80; CHECK-NEXT: br label [[FOR_BODY:%.*]] 81; CHECK: for.body: 82; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[DEC_INT:%.*]], [[FOR_BODY]] ] 83; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to float 84; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[INDVAR_CONV]] to i16 85; CHECK-NEXT: [[IDXPROM32:%.*]] = sext i16 [[CONV]] to i32 86; CHECK-NEXT: [[IDXPROM64:%.*]] = sext i16 [[CONV]] to i64 87; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 [[IDXPROM64]] 88; CHECK-NEXT: store i32 [[IDXPROM32]], i32* [[ARRAYIDX]], align 4 89; CHECK-NEXT: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 90; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 0 91; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP:%.*]] 92; CHECK: cleanup: 93; CHECK-NEXT: ret void 94; 95entry: 96 br label %for.body 97 98for.body: ; preds = %for.body, %entry 99 %iv.int = phi i32 [ 100, %entry ], [ %dec.int, %for.body ] 100 %indvar.conv = sitofp i32 %iv.int to float 101 %conv = fptosi float %indvar.conv to i16 102 %idxprom32 = sext i16 %conv to i32 103 %idxprom64 = sext i16 %conv to i64 104 %arrayidx = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 %idxprom64 105 store i32 %idxprom32, i32* %arrayidx, align 4 106 %dec.int = add nsw i32 %iv.int, -1 107 %cmp = icmp ugt i32 %dec.int, 0 108 br i1 %cmp, label %for.body, label %cleanup 109 110cleanup: ; preds = %for.body 111 ret void 112} 113