1555 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -passes='reassociate' -S < %s | FileCheck %s --check-prefix=REASSOCIATE_ONLY3; RUN: opt -passes='licm' -S < %s | FileCheck %s --check-prefix=LICM_ONLY4; RUN: opt -passes='licm' -licm-max-num-fp-reassociations=1 -S < %s | FileCheck %s --check-prefix=LICM_ONLY_CONSTRAINED5; RUN: opt -passes='reassociate,loop-mssa(licm)' -S < %s | FileCheck %s --check-prefix=LICM_AFTER_REASSOCIATE6; RUN: opt -passes='reassociate,loop-mssa(licm)' -licm-max-num-fp-reassociations=1 -S < %s | FileCheck %s --check-prefix=LICM_AFTER_REASSOCIATE_CONSTRAINED7 8;9; A simple loop, should not get modified:10;11; int j;12; const double d1d = d1 * delta;13;14; for (j = 0; j <= i; j++)15; cells[j] = d1d * cells[j + 1];16;17 18define void @innermost_loop_1d_fast(i32 %i, double %d1, double %delta, ptr %cells) {19; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_1d_fast20; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {21; REASSOCIATE_ONLY-NEXT: entry:22; REASSOCIATE_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]23; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]24; REASSOCIATE_ONLY: for.cond:25; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]26; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]27; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]28; REASSOCIATE_ONLY: for.body:29; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 130; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i6431; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]32; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 833; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]34; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i6435; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]36; REASSOCIATE_ONLY-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 837; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]38; REASSOCIATE_ONLY: for.end:39; REASSOCIATE_ONLY-NEXT: ret void40;41; LICM_ONLY-LABEL: define void @innermost_loop_1d_fast42; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {43; LICM_ONLY-NEXT: entry:44; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]45; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]46; LICM_ONLY: for.cond:47; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]48; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]49; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]50; LICM_ONLY: for.body:51; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 152; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i6453; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]54; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 855; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]56; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i6457; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]58; LICM_ONLY-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 859; LICM_ONLY-NEXT: br label [[FOR_COND]]60; LICM_ONLY: for.end:61; LICM_ONLY-NEXT: ret void62;63; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_1d_fast64; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {65; LICM_ONLY_CONSTRAINED-NEXT: entry:66; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]67; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]68; LICM_ONLY_CONSTRAINED: for.cond:69; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]70; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]71; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]72; LICM_ONLY_CONSTRAINED: for.body:73; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 174; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i6475; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]76; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 877; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]78; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i6479; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]80; LICM_ONLY_CONSTRAINED-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 881; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]82; LICM_ONLY_CONSTRAINED: for.end:83; LICM_ONLY_CONSTRAINED-NEXT: ret void84;85; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_1d_fast86; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {87; LICM_AFTER_REASSOCIATE-NEXT: entry:88; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]89; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]90; LICM_AFTER_REASSOCIATE: for.cond:91; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]92; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]93; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]94; LICM_AFTER_REASSOCIATE: for.body:95; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 196; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i6497; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]98; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 899; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]100; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64101; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]102; LICM_AFTER_REASSOCIATE-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8103; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]104; LICM_AFTER_REASSOCIATE: for.end:105; LICM_AFTER_REASSOCIATE-NEXT: ret void106;107; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_1d_fast108; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {109; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:110; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]111; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]112; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:113; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]114; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]115; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]116; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:117; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1118; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64119; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]120; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8121; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]122; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64123; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]124; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8125; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]126; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:127; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void128;129entry:130 %fmul.d1 = fmul fast double %d1, %delta131 br label %for.cond132 133for.cond:134 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]135 %cmp.not = icmp sgt i32 %j, %i136 br i1 %cmp.not, label %for.end, label %for.body137 138for.body:139 %add.j.1 = add nuw nsw i32 %j, 1140 %idxprom.j.1 = zext i32 %add.j.1 to i64141 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1142 %cell.1 = load double, ptr %arrayidx.j.1, align 8143 %fmul.1 = fmul fast double %fmul.d1, %cell.1144 %idxprom.j = zext i32 %j to i64145 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j146 store double %fmul.1, ptr %arrayidx.j, align 8147 br label %for.cond148 149for.end:150 ret void151}152 153;154; A simple loop:155;156; int j;157;158; for (j = 0; j <= i; j++)159; cells[j] = d1 * cells[j + 1] * delta;160;161; ...should be transformed by the LICM pass into this:162;163; int j;164; const double d1d = d1 * delta;165;166; for (j = 0; j <= i; j++)167; cells[j] = d1d * cells[j + 1];168;169 170define void @innermost_loop_1d_shouldhoist_fast(i32 %i, double %d1, double %delta, ptr %cells) {171; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_1d_shouldhoist_fast172; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {173; REASSOCIATE_ONLY-NEXT: entry:174; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]175; REASSOCIATE_ONLY: for.cond:176; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]177; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]178; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]179; REASSOCIATE_ONLY: for.body:180; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1181; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64182; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]183; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8184; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]185; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]186; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64187; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]188; REASSOCIATE_ONLY-NEXT: store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8189; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]190; REASSOCIATE_ONLY: for.end:191; REASSOCIATE_ONLY-NEXT: ret void192;193; LICM_ONLY-LABEL: define void @innermost_loop_1d_shouldhoist_fast194; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {195; LICM_ONLY-NEXT: entry:196; LICM_ONLY-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]197; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]198; LICM_ONLY: for.cond:199; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]200; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]201; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]202; LICM_ONLY: for.body:203; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1204; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64205; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]206; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8207; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FACTOR_OP_FMUL]], [[CELL_1]]208; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64209; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]210; LICM_ONLY-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8211; LICM_ONLY-NEXT: br label [[FOR_COND]]212; LICM_ONLY: for.end:213; LICM_ONLY-NEXT: ret void214;215; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_1d_shouldhoist_fast216; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {217; LICM_ONLY_CONSTRAINED-NEXT: entry:218; LICM_ONLY_CONSTRAINED-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]219; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]220; LICM_ONLY_CONSTRAINED: for.cond:221; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]222; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]223; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]224; LICM_ONLY_CONSTRAINED: for.body:225; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1226; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64227; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]228; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8229; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FACTOR_OP_FMUL]], [[CELL_1]]230; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64231; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]232; LICM_ONLY_CONSTRAINED-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8233; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]234; LICM_ONLY_CONSTRAINED: for.end:235; LICM_ONLY_CONSTRAINED-NEXT: ret void236;237; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_1d_shouldhoist_fast238; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {239; LICM_AFTER_REASSOCIATE-NEXT: entry:240; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]241; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]242; LICM_AFTER_REASSOCIATE: for.cond:243; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]244; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]245; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]246; LICM_AFTER_REASSOCIATE: for.body:247; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1248; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64249; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]250; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8251; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]252; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64253; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]254; LICM_AFTER_REASSOCIATE-NEXT: store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8255; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]256; LICM_AFTER_REASSOCIATE: for.end:257; LICM_AFTER_REASSOCIATE-NEXT: ret void258;259; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_1d_shouldhoist_fast260; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {261; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:262; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]263; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]264; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:265; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]266; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]267; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]268; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:269; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1270; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64271; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]272; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8273; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]274; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64275; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]276; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8277; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]278; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:279; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void280;281entry:282 br label %for.cond283 284for.cond:285 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]286 %cmp.not = icmp sgt i32 %j, %i287 br i1 %cmp.not, label %for.end, label %for.body288 289for.body:290 %add.j.1 = add nuw nsw i32 %j, 1291 %idxprom.j.1 = zext i32 %add.j.1 to i64292 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1293 %cell.1 = load double, ptr %arrayidx.j.1, align 8294 %fmul.1 = fmul fast double %d1, %cell.1295 %fmul.2 = fmul fast double %fmul.1, %delta296 %idxprom.j = zext i32 %j to i64297 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j298 store double %fmul.2, ptr %arrayidx.j, align 8299 br label %for.cond300 301for.end:302 ret void303}304 305;306; The following loop will be modified by the 'Reassociate expressions' pass,307;308; int j;309; const double d1d = d1 * delta;310; const double d2d = d2 * delta;311;312; for (j = 0; j <= i; j++)313; cells[j] = d1d * cells[j + 1] + d2d * cells[j];314;315; ...into this:316;317; int j;318;319; for (j = 0; j <= i; j++)320; cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;321;322; We expect the LICM pass to undo this transformation.323;324 325define void @innermost_loop_2d_fast(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {326; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_fast327; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {328; REASSOCIATE_ONLY-NEXT: entry:329; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]330; REASSOCIATE_ONLY: for.cond:331; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]332; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]333; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]334; REASSOCIATE_ONLY: for.body:335; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1336; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64337; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]338; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8339; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]340; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64341; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]342; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8343; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]344; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]345; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]346; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8347; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]348; REASSOCIATE_ONLY: for.end:349; REASSOCIATE_ONLY-NEXT: ret void350;351; LICM_ONLY-LABEL: define void @innermost_loop_2d_fast352; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {353; LICM_ONLY-NEXT: entry:354; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]355; LICM_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]356; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]357; LICM_ONLY: for.cond:358; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]359; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]360; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]361; LICM_ONLY: for.body:362; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1363; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64364; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]365; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8366; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]367; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64368; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]369; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8370; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]371; LICM_ONLY-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]372; LICM_ONLY-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8373; LICM_ONLY-NEXT: br label [[FOR_COND]]374; LICM_ONLY: for.end:375; LICM_ONLY-NEXT: ret void376;377; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast378; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {379; LICM_ONLY_CONSTRAINED-NEXT: entry:380; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]381; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]382; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]383; LICM_ONLY_CONSTRAINED: for.cond:384; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]385; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]386; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]387; LICM_ONLY_CONSTRAINED: for.body:388; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1389; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64390; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]391; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8392; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]393; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64394; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]395; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8396; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]397; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]398; LICM_ONLY_CONSTRAINED-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8399; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]400; LICM_ONLY_CONSTRAINED: for.end:401; LICM_ONLY_CONSTRAINED-NEXT: ret void402;403; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_fast404; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {405; LICM_AFTER_REASSOCIATE-NEXT: entry:406; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]407; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]408; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]409; LICM_AFTER_REASSOCIATE: for.cond:410; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]411; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]412; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]413; LICM_AFTER_REASSOCIATE: for.body:414; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1415; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64416; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]417; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8418; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]419; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64420; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]421; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8422; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]423; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]424; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8425; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]426; LICM_AFTER_REASSOCIATE: for.end:427; LICM_AFTER_REASSOCIATE-NEXT: ret void428;429; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast430; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {431; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:432; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]433; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:434; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]435; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]436; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]437; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:438; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1439; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64440; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]441; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8442; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]443; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64444; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]445; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8446; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]447; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]448; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]449; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8450; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]451; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:452; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void453;454entry:455 %fmul.d1 = fmul fast double %d1, %delta456 %fmul.d2 = fmul fast double %d2, %delta457 br label %for.cond458 459for.cond:460 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]461 %cmp.not = icmp sgt i32 %j, %i462 br i1 %cmp.not, label %for.end, label %for.body463 464for.body:465 %add.j.1 = add nuw nsw i32 %j, 1466 %idxprom.j.1 = zext i32 %add.j.1 to i64467 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1468 %cell.1 = load double, ptr %arrayidx.j.1, align 8469 %fmul.1 = fmul fast double %fmul.d1, %cell.1470 %idxprom.j = zext i32 %j to i64471 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j472 %cell.2 = load double, ptr %arrayidx.j, align 8473 %fmul.2 = fmul fast double %fmul.d2, %cell.2474 %fadd.1 = fadd fast double %fmul.1, %fmul.2475 store double %fadd.1, ptr %arrayidx.j, align 8476 br label %for.cond477 478for.end:479 ret void480}481 482;483; The following loop will be modified by the 'Reassociate expressions' pass,484;485; int j;486; const double d1d = d1 * delta;487; const double d2d = d2 * delta;488; const double d3d = d3 * delta;489;490; for (j = 0; j <= i; j++)491; cells[j] = d1d * cells[j + 1] + d2d * cells[j] + d3d * cells[j + 2];492;493; ...into this:494;495; int j;496;497; for (j = 0; j <= i; j++)498; cells[j] = (d1 * cells[j + 1] + d2 * cells[j] + d3 * cells[j + 2]) * delta;499;500; We expect the LICM pass to undo this transformation.501;502 503 504define void @innermost_loop_3d_fast(i32 %i, double %d1, double %d2, double %d3, double %delta, ptr %cells) {505; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_3d_fast506; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {507; REASSOCIATE_ONLY-NEXT: entry:508; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]509; REASSOCIATE_ONLY: for.cond:510; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]511; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]512; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]513; REASSOCIATE_ONLY: for.body:514; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1515; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64516; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]517; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8518; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]519; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64520; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]521; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8522; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]523; REASSOCIATE_ONLY-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2524; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64525; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]526; REASSOCIATE_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8527; REASSOCIATE_ONLY-NEXT: [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[D3]]528; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]529; REASSOCIATE_ONLY-NEXT: [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]530; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD1]], [[DELTA]]531; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J_2]], align 8532; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]533; REASSOCIATE_ONLY: for.end:534; REASSOCIATE_ONLY-NEXT: ret void535;536; LICM_ONLY-LABEL: define void @innermost_loop_3d_fast537; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {538; LICM_ONLY-NEXT: entry:539; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]540; LICM_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]541; LICM_ONLY-NEXT: [[FMUL_D3:%.*]] = fmul fast double [[D3]], [[DELTA]]542; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]543; LICM_ONLY: for.cond:544; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]545; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]546; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]547; LICM_ONLY: for.body:548; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1549; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64550; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]551; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8552; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]553; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64554; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]555; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8556; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]557; LICM_ONLY-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]558; LICM_ONLY-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2559; LICM_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64560; LICM_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]561; LICM_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8562; LICM_ONLY-NEXT: [[FMUL_3:%.*]] = fmul fast double [[FMUL_D3]], [[CELL_3]]563; LICM_ONLY-NEXT: [[FADD_2:%.*]] = fadd fast double [[FADD_1]], [[FMUL_3]]564; LICM_ONLY-NEXT: store double [[FADD_2]], ptr [[ARRAYIDX_J_2]], align 8565; LICM_ONLY-NEXT: br label [[FOR_COND]]566; LICM_ONLY: for.end:567; LICM_ONLY-NEXT: ret void568;569; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast570; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {571; LICM_ONLY_CONSTRAINED-NEXT: entry:572; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]573; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]574; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D3:%.*]] = fmul fast double [[D3]], [[DELTA]]575; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]576; LICM_ONLY_CONSTRAINED: for.cond:577; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]578; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]579; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]580; LICM_ONLY_CONSTRAINED: for.body:581; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1582; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64583; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]584; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8585; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]586; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64587; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]588; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8589; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]590; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]591; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2592; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64593; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]594; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8595; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_3:%.*]] = fmul fast double [[FMUL_D3]], [[CELL_3]]596; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_2:%.*]] = fadd fast double [[FADD_1]], [[FMUL_3]]597; LICM_ONLY_CONSTRAINED-NEXT: store double [[FADD_2]], ptr [[ARRAYIDX_J_2]], align 8598; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]599; LICM_ONLY_CONSTRAINED: for.end:600; LICM_ONLY_CONSTRAINED-NEXT: ret void601;602; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_3d_fast603; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {604; LICM_AFTER_REASSOCIATE-NEXT: entry:605; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D3]], [[DELTA]]606; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL2:%.*]] = fmul fast double [[D1]], [[DELTA]]607; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL3:%.*]] = fmul fast double [[D2]], [[DELTA]]608; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]609; LICM_AFTER_REASSOCIATE: for.cond:610; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]611; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]612; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]613; LICM_AFTER_REASSOCIATE: for.body:614; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1615; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64616; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]617; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8618; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL2]]619; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64620; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]621; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8622; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL3]]623; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2624; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64625; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]626; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8627; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[FACTOR_OP_FMUL]]628; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]629; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]630; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_ADD1]], ptr [[ARRAYIDX_J_2]], align 8631; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]632; LICM_AFTER_REASSOCIATE: for.end:633; LICM_AFTER_REASSOCIATE-NEXT: ret void634;635; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast636; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {637; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:638; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]639; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:640; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]641; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]642; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]643; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:644; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1645; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64646; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]647; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8648; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]649; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64650; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]651; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8652; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]653; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2654; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64655; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]656; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8657; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[D3]]658; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]659; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]660; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD1]], [[DELTA]]661; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J_2]], align 8662; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]663; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:664; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void665;666entry:667 %fmul.d1 = fmul fast double %d1, %delta668 %fmul.d2 = fmul fast double %d2, %delta669 %fmul.d3 = fmul fast double %d3, %delta670 br label %for.cond671 672for.cond:673 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]674 %cmp.not = icmp sgt i32 %j, %i675 br i1 %cmp.not, label %for.end, label %for.body676 677for.body:678 %add.j.1 = add nuw nsw i32 %j, 1679 %idxprom.j.1 = zext i32 %add.j.1 to i64680 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1681 %cell.1 = load double, ptr %arrayidx.j.1, align 8682 %fmul.1 = fmul fast double %fmul.d1, %cell.1683 %idxprom.j = zext i32 %j to i64684 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j685 %cell.2 = load double, ptr %arrayidx.j, align 8686 %fmul.2 = fmul fast double %fmul.d2, %cell.2687 %fadd.1 = fadd fast double %fmul.1, %fmul.2688 %add.j.2 = add nuw nsw i32 %j, 2689 %idxprom.j.2 = zext i32 %add.j.2 to i64690 %arrayidx.j.2 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.2691 %cell.3 = load double, ptr %arrayidx.j.2, align 8692 %fmul.3 = fmul fast double %fmul.d3, %cell.3693 %fadd.2 = fadd fast double %fadd.1, %fmul.3694 store double %fadd.2, ptr %arrayidx.j.2, align 8695 br label %for.cond696 697for.end:698 ret void699}700 701;702; When there is no 'fast' attribute, the transformation should not happen.703;704 705define void @innermost_loop_2d_nofast(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {706; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nofast707; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {708; REASSOCIATE_ONLY-NEXT: entry:709; REASSOCIATE_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]710; REASSOCIATE_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]711; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]712; REASSOCIATE_ONLY: for.cond:713; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]714; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]715; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]716; REASSOCIATE_ONLY: for.body:717; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1718; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64719; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]720; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8721; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]722; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64723; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]724; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8725; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]726; REASSOCIATE_ONLY-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]727; REASSOCIATE_ONLY-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8728; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]729; REASSOCIATE_ONLY: for.end:730; REASSOCIATE_ONLY-NEXT: ret void731;732; LICM_ONLY-LABEL: define void @innermost_loop_2d_nofast733; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {734; LICM_ONLY-NEXT: entry:735; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]736; LICM_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]737; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]738; LICM_ONLY: for.cond:739; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]740; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]741; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]742; LICM_ONLY: for.body:743; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1744; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64745; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]746; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8747; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]748; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64749; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]750; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8751; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]752; LICM_ONLY-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]753; LICM_ONLY-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8754; LICM_ONLY-NEXT: br label [[FOR_COND]]755; LICM_ONLY: for.end:756; LICM_ONLY-NEXT: ret void757;758; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast759; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {760; LICM_ONLY_CONSTRAINED-NEXT: entry:761; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]762; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]763; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]764; LICM_ONLY_CONSTRAINED: for.cond:765; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]766; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]767; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]768; LICM_ONLY_CONSTRAINED: for.body:769; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1770; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64771; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]772; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8773; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]774; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64775; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]776; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8777; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]778; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]779; LICM_ONLY_CONSTRAINED-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8780; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]781; LICM_ONLY_CONSTRAINED: for.end:782; LICM_ONLY_CONSTRAINED-NEXT: ret void783;784; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nofast785; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {786; LICM_AFTER_REASSOCIATE-NEXT: entry:787; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]788; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]789; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]790; LICM_AFTER_REASSOCIATE: for.cond:791; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]792; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]793; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]794; LICM_AFTER_REASSOCIATE: for.body:795; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1796; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64797; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]798; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8799; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]800; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64801; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]802; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8803; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]804; LICM_AFTER_REASSOCIATE-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]805; LICM_AFTER_REASSOCIATE-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8806; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]807; LICM_AFTER_REASSOCIATE: for.end:808; LICM_AFTER_REASSOCIATE-NEXT: ret void809;810; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast811; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {812; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:813; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]814; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]815; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]816; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:817; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]818; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]819; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]820; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:821; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1822; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64823; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]824; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8825; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]826; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64827; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]828; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8829; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]830; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]831; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8832; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]833; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:834; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void835;836entry:837 %fmul.d1 = fmul double %d1, %delta838 %fmul.d2 = fmul double %d2, %delta839 br label %for.cond840 841for.cond:842 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]843 %cmp.not = icmp sgt i32 %j, %i844 br i1 %cmp.not, label %for.end, label %for.body845 846for.body:847 %add.j.1 = add nuw nsw i32 %j, 1848 %idxprom.j.1 = zext i32 %add.j.1 to i64849 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1850 %cell.1 = load double, ptr %arrayidx.j.1, align 8851 %fmul.1 = fmul double %fmul.d1, %cell.1852 %idxprom.j = zext i32 %j to i64853 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j854 %cell.2 = load double, ptr %arrayidx.j, align 8855 %fmul.2 = fmul double %fmul.d2, %cell.2856 %fadd.1 = fadd double %fmul.1, %fmul.2857 store double %fadd.1, ptr %arrayidx.j, align 8858 br label %for.cond859 860for.end:861 ret void862}863 864;865; The following loop should be modified by the LICM pass,866;867; int j;868;869; for (j = 0; j <= i; j++)870; cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;871;872; ...into this:873;874; int j;875; const double d1d = d1 * delta;876; const double d2d = d2 * delta;877;878; for (j = 0; j <= i; j++)879; cells[j] = d1d * cells[j + 1] + d2d * cells[j];880;881 882define void @innermost_loop_2d_fast_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {883; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_fast_reassociated884; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {885; REASSOCIATE_ONLY-NEXT: entry:886; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]887; REASSOCIATE_ONLY: for.cond:888; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]889; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]890; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]891; REASSOCIATE_ONLY: for.body:892; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1893; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64894; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]895; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8896; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]897; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64898; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]899; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8900; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]901; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]902; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]903; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8904; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]905; REASSOCIATE_ONLY: for.end:906; REASSOCIATE_ONLY-NEXT: ret void907;908; LICM_ONLY-LABEL: define void @innermost_loop_2d_fast_reassociated909; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {910; LICM_ONLY-NEXT: entry:911; LICM_ONLY-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]912; LICM_ONLY-NEXT: [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]913; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]914; LICM_ONLY: for.cond:915; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]916; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]917; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]918; LICM_ONLY: for.body:919; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1920; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64921; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]922; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8923; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]924; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64925; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]926; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8927; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]928; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]929; LICM_ONLY-NEXT: store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8930; LICM_ONLY-NEXT: br label [[FOR_COND]]931; LICM_ONLY: for.end:932; LICM_ONLY-NEXT: ret void933;934; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast_reassociated935; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {936; LICM_ONLY_CONSTRAINED-NEXT: entry:937; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]938; LICM_ONLY_CONSTRAINED: for.cond:939; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]940; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]941; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]942; LICM_ONLY_CONSTRAINED: for.body:943; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1944; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64945; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]946; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8947; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]948; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64949; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]950; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8951; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]952; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]953; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]954; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8955; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]956; LICM_ONLY_CONSTRAINED: for.end:957; LICM_ONLY_CONSTRAINED-NEXT: ret void958;959; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_fast_reassociated960; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {961; LICM_AFTER_REASSOCIATE-NEXT: entry:962; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]963; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]964; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]965; LICM_AFTER_REASSOCIATE: for.cond:966; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]967; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]968; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]969; LICM_AFTER_REASSOCIATE: for.body:970; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1971; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64972; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]973; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8974; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]975; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64976; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]977; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8978; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]979; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]980; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8981; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]982; LICM_AFTER_REASSOCIATE: for.end:983; LICM_AFTER_REASSOCIATE-NEXT: ret void984;985; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast_reassociated986; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {987; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:988; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]989; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:990; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]991; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]992; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]993; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:994; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1995; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64996; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]997; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8998; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]999; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641000; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1001; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81002; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]1003; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]1004; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]1005; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81006; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]1007; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:1008; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void1009;1010entry:1011 br label %for.cond1012 1013for.cond:1014 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]1015 %cmp.not = icmp sgt i32 %j, %i1016 br i1 %cmp.not, label %for.end, label %for.body1017 1018for.body:1019 %add.j.1 = add nuw nsw i32 %j, 11020 %idxprom.j.1 = zext i32 %add.j.1 to i641021 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.11022 %cell.1 = load double, ptr %arrayidx.j.1, align 81023 %fmul.1 = fmul fast double %cell.1, %d11024 %idxprom.j = zext i32 %j to i641025 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j1026 %cell.2 = load double, ptr %arrayidx.j, align 81027 %fmul.2 = fmul fast double %cell.2, %d21028 %reass.add = fadd fast double %fmul.2, %fmul.11029 %reass.mul = fmul fast double %reass.add, %delta1030 store double %reass.mul, ptr %arrayidx.j, align 81031 br label %for.cond1032 1033for.end:1034 ret void1035}1036 1037;1038; When there is no 'fast' attribute, the transformation should not happen.1039;1040 1041define void @innermost_loop_2d_nofast_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {1042; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nofast_reassociated1043; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1044; REASSOCIATE_ONLY-NEXT: entry:1045; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]1046; REASSOCIATE_ONLY: for.cond:1047; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1048; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1049; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1050; REASSOCIATE_ONLY: for.body:1051; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11052; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641053; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1054; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81055; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]1056; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641057; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1058; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81059; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]1060; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]1061; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]1062; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81063; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]1064; REASSOCIATE_ONLY: for.end:1065; REASSOCIATE_ONLY-NEXT: ret void1066;1067; LICM_ONLY-LABEL: define void @innermost_loop_2d_nofast_reassociated1068; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1069; LICM_ONLY-NEXT: entry:1070; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]1071; LICM_ONLY: for.cond:1072; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1073; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1074; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1075; LICM_ONLY: for.body:1076; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11077; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641078; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1079; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81080; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[CELL_1]], [[D1]]1081; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641082; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1083; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81084; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[CELL_2]], [[D2]]1085; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_2]], [[FMUL_1]]1086; LICM_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul double [[REASS_ADD]], [[DELTA]]1087; LICM_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81088; LICM_ONLY-NEXT: br label [[FOR_COND]]1089; LICM_ONLY: for.end:1090; LICM_ONLY-NEXT: ret void1091;1092; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast_reassociated1093; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1094; LICM_ONLY_CONSTRAINED-NEXT: entry:1095; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]1096; LICM_ONLY_CONSTRAINED: for.cond:1097; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1098; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1099; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1100; LICM_ONLY_CONSTRAINED: for.body:1101; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11102; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641103; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1104; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81105; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[CELL_1]], [[D1]]1106; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641107; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1108; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81109; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[CELL_2]], [[D2]]1110; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_2]], [[FMUL_1]]1111; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul double [[REASS_ADD]], [[DELTA]]1112; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81113; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]1114; LICM_ONLY_CONSTRAINED: for.end:1115; LICM_ONLY_CONSTRAINED-NEXT: ret void1116;1117; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nofast_reassociated1118; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1119; LICM_AFTER_REASSOCIATE-NEXT: entry:1120; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]1121; LICM_AFTER_REASSOCIATE: for.cond:1122; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1123; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1124; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1125; LICM_AFTER_REASSOCIATE: for.body:1126; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11127; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641128; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1129; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81130; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]1131; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641132; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1133; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81134; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]1135; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]1136; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]1137; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81138; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]1139; LICM_AFTER_REASSOCIATE: for.end:1140; LICM_AFTER_REASSOCIATE-NEXT: ret void1141;1142; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast_reassociated1143; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1144; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:1145; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]1146; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:1147; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1148; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1149; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1150; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:1151; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11152; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641153; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1154; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81155; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]1156; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641157; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1158; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81159; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]1160; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]1161; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]1162; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81163; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]1164; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:1165; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void1166;1167entry:1168 br label %for.cond1169 1170for.cond:1171 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]1172 %cmp.not = icmp sgt i32 %j, %i1173 br i1 %cmp.not, label %for.end, label %for.body1174 1175for.body:1176 %add.j.1 = add nuw nsw i32 %j, 11177 %idxprom.j.1 = zext i32 %add.j.1 to i641178 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.11179 %cell.1 = load double, ptr %arrayidx.j.1, align 81180 %fmul.1 = fmul double %cell.1, %d11181 %idxprom.j = zext i32 %j to i641182 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j1183 %cell.2 = load double, ptr %arrayidx.j, align 81184 %fmul.2 = fmul double %cell.2, %d21185 %reass.add = fadd double %fmul.2, %fmul.11186 %reass.mul = fmul double %reass.add, %delta1187 store double %reass.mul, ptr %arrayidx.j, align 81188 br label %for.cond1189 1190for.end:1191 ret void1192}1193;1194; When there is no 'nsz' attribute, the transformation should not happen.1195;1196 1197define void @innermost_loop_2d_nonsz_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {1198; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nonsz_reassociated1199; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1200; REASSOCIATE_ONLY-NEXT: entry:1201; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]1202; REASSOCIATE_ONLY: for.cond:1203; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1204; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1205; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1206; REASSOCIATE_ONLY: for.body:1207; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11208; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641209; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1210; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81211; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul reassoc double [[D1]], [[CELL_1]]1212; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641213; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1214; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81215; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul reassoc double [[D2]], [[CELL_2]]1216; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_1]], [[FMUL_2]]1217; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul reassoc double [[DELTA]], [[REASS_ADD]]1218; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81219; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]1220; REASSOCIATE_ONLY: for.end:1221; REASSOCIATE_ONLY-NEXT: ret void1222;1223; LICM_ONLY-LABEL: define void @innermost_loop_2d_nonsz_reassociated1224; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1225; LICM_ONLY-NEXT: entry:1226; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]1227; LICM_ONLY: for.cond:1228; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1229; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1230; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1231; LICM_ONLY: for.body:1232; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11233; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641234; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1235; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81236; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul reassoc double [[CELL_1]], [[D1]]1237; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641238; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1239; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81240; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul reassoc double [[CELL_2]], [[D2]]1241; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_2]], [[FMUL_1]]1242; LICM_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul reassoc double [[REASS_ADD]], [[DELTA]]1243; LICM_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81244; LICM_ONLY-NEXT: br label [[FOR_COND]]1245; LICM_ONLY: for.end:1246; LICM_ONLY-NEXT: ret void1247;1248; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nonsz_reassociated1249; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1250; LICM_ONLY_CONSTRAINED-NEXT: entry:1251; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]1252; LICM_ONLY_CONSTRAINED: for.cond:1253; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1254; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1255; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1256; LICM_ONLY_CONSTRAINED: for.body:1257; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11258; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641259; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1260; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81261; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul reassoc double [[CELL_1]], [[D1]]1262; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641263; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1264; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81265; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul reassoc double [[CELL_2]], [[D2]]1266; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_2]], [[FMUL_1]]1267; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul reassoc double [[REASS_ADD]], [[DELTA]]1268; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81269; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]1270; LICM_ONLY_CONSTRAINED: for.end:1271; LICM_ONLY_CONSTRAINED-NEXT: ret void1272;1273; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nonsz_reassociated1274; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1275; LICM_AFTER_REASSOCIATE-NEXT: entry:1276; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]1277; LICM_AFTER_REASSOCIATE: for.cond:1278; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1279; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1280; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1281; LICM_AFTER_REASSOCIATE: for.body:1282; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11283; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641284; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1285; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81286; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul reassoc double [[D1]], [[CELL_1]]1287; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641288; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1289; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81290; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul reassoc double [[D2]], [[CELL_2]]1291; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_1]], [[FMUL_2]]1292; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_MUL:%.*]] = fmul reassoc double [[DELTA]], [[REASS_ADD]]1293; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81294; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]1295; LICM_AFTER_REASSOCIATE: for.end:1296; LICM_AFTER_REASSOCIATE-NEXT: ret void1297;1298; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nonsz_reassociated1299; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1300; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:1301; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]1302; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:1303; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1304; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1305; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1306; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:1307; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11308; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641309; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1310; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81311; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul reassoc double [[D1]], [[CELL_1]]1312; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641313; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1314; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81315; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul reassoc double [[D2]], [[CELL_2]]1316; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd reassoc double [[FMUL_1]], [[FMUL_2]]1317; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul reassoc double [[DELTA]], [[REASS_ADD]]1318; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81319; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]1320; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:1321; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void1322;1323entry:1324 br label %for.cond1325 1326for.cond:1327 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]1328 %cmp.not = icmp sgt i32 %j, %i1329 br i1 %cmp.not, label %for.end, label %for.body1330 1331for.body:1332 %add.j.1 = add nuw nsw i32 %j, 11333 %idxprom.j.1 = zext i32 %add.j.1 to i641334 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.11335 %cell.1 = load double, ptr %arrayidx.j.1, align 81336 %fmul.1 = fmul reassoc double %cell.1, %d11337 %idxprom.j = zext i32 %j to i641338 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j1339 %cell.2 = load double, ptr %arrayidx.j, align 81340 %fmul.2 = fmul reassoc double %cell.2, %d21341 %reass.add = fadd reassoc double %fmul.2, %fmul.11342 %reass.mul = fmul reassoc double %reass.add, %delta1343 store double %reass.mul, ptr %arrayidx.j, align 81344 br label %for.cond1345 1346for.end:1347 ret void1348}1349 1350;1351; The following loop will not be modified by the LICM pass:1352;1353; int j;1354;1355; for (j = 0; j <= i; j++)1356; cells[j] = (d1 * cells[j + 1] + d2 * cells[j] +1357; cells[j] * cells[j + 1]) * delta;1358;1359; This case differs as one of the multiplications involves no invariants.1360;1361 1362define void @innermost_loop_3d_fast_reassociated_different(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {1363; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_3d_fast_reassociated_different1364; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1365; REASSOCIATE_ONLY-NEXT: entry:1366; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]1367; REASSOCIATE_ONLY: for.cond:1368; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1369; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1370; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1371; REASSOCIATE_ONLY: for.body:1372; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11373; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641374; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1375; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81376; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i641377; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]1378; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81379; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_3:%.*]] = zext i32 [[ADD_J_1]] to i641380; REASSOCIATE_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81381; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641382; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1383; REASSOCIATE_ONLY-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81384; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]1385; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]1386; REASSOCIATE_ONLY-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]1387; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]1388; REASSOCIATE_ONLY-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]1389; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]1390; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81391; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]1392; REASSOCIATE_ONLY: for.end:1393; REASSOCIATE_ONLY-NEXT: ret void1394;1395; LICM_ONLY-LABEL: define void @innermost_loop_3d_fast_reassociated_different1396; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1397; LICM_ONLY-NEXT: entry:1398; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]1399; LICM_ONLY: for.cond:1400; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1401; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1402; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1403; LICM_ONLY: for.body:1404; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11405; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641406; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1407; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81408; LICM_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i641409; LICM_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]1410; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81411; LICM_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81412; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641413; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1414; LICM_ONLY-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81415; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]1416; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]1417; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]1418; LICM_ONLY-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]1419; LICM_ONLY-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[REASS_ADD]]1420; LICM_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]1421; LICM_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81422; LICM_ONLY-NEXT: br label [[FOR_COND]]1423; LICM_ONLY: for.end:1424; LICM_ONLY-NEXT: ret void1425;1426; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast_reassociated_different1427; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1428; LICM_ONLY_CONSTRAINED-NEXT: entry:1429; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]1430; LICM_ONLY_CONSTRAINED: for.cond:1431; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1432; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1433; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1434; LICM_ONLY_CONSTRAINED: for.body:1435; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11436; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641437; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1438; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81439; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i641440; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]1441; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81442; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81443; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641444; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1445; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81446; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]1447; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]1448; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]1449; LICM_ONLY_CONSTRAINED-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]1450; LICM_ONLY_CONSTRAINED-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[REASS_ADD]]1451; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]1452; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81453; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]1454; LICM_ONLY_CONSTRAINED: for.end:1455; LICM_ONLY_CONSTRAINED-NEXT: ret void1456;1457; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_3d_fast_reassociated_different1458; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1459; LICM_AFTER_REASSOCIATE-NEXT: entry:1460; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]1461; LICM_AFTER_REASSOCIATE: for.cond:1462; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1463; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1464; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1465; LICM_AFTER_REASSOCIATE: for.body:1466; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11467; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641468; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1469; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81470; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i641471; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]1472; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81473; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81474; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641475; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1476; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81477; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]1478; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]1479; LICM_AFTER_REASSOCIATE-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]1480; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]1481; LICM_AFTER_REASSOCIATE-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]1482; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]1483; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81484; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]1485; LICM_AFTER_REASSOCIATE: for.end:1486; LICM_AFTER_REASSOCIATE-NEXT: ret void1487;1488; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast_reassociated_different1489; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {1490; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:1491; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]1492; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:1493; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]1494; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]1495; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]1496; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:1497; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 11498; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i641499; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]1500; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 81501; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i641502; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]1503; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81504; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 81505; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i641506; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]1507; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 81508; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]1509; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]1510; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]1511; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]1512; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]1513; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]1514; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 81515; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]1516; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:1517; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void1518;1519entry:1520 br label %for.cond1521 1522for.cond:1523 %j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]1524 %cmp.not = icmp sgt i32 %j, %i1525 br i1 %cmp.not, label %for.end, label %for.body1526 1527for.body:1528 %add.j.1 = add nuw nsw i32 %j, 11529 %idxprom.j.1 = zext i32 %add.j.1 to i641530 %arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.11531 %cell.1 = load double, ptr %arrayidx.j.1, align 81532 %add.j.2 = add nuw nsw i32 %j, 21533 %idxprom.j.2 = zext i32 %add.j.1 to i641534 %arrayidx.j.2 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.21535 %cell.2 = load double, ptr %arrayidx.j.2, align 81536 %add.j.3 = add nuw nsw i32 %j, 31537 %idxprom.j.3 = zext i32 %add.j.1 to i641538 %arrayidx.j.3 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.31539 %cell.3 = load double, ptr %arrayidx.j.2, align 81540 %idxprom.j = zext i32 %j to i641541 %arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j1542 %cell.4 = load double, ptr %arrayidx.j, align 81543 %fmul.1 = fmul fast double %cell.1, %d11544 %fmul.2 = fmul fast double %cell.4, %d21545 %reass.add = fadd fast double %fmul.2, %fmul.11546 %extra.mul = fmul fast double %cell.3, %cell.21547 %extra.add = fadd fast double %extra.mul, %reass.add1548 %reass.mul = fmul fast double %extra.add, %delta1549 store double %reass.mul, ptr %arrayidx.j, align 81550 br label %for.cond1551 1552for.end:1553 ret void1554}1555