Consider the following piece of code:
```
void innermost_loop(int i, double d1, double d2, double delta, int n, double cells[n])
{
int j;
const double d1d = d1 * delta;
const double d2d = d2 * delta;
for (j = 0; j <= i; j++)
cells[j] = d1d * cells[j + 1] + d2d * cells[j];
}
```
When compiling at -Ofast level, after the "Reassociate expressions"
pass, this code is transformed into an equivalent of:
```
int j;
for (j = 0; j <= i; j++)
cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;
```
Effectively, the computation of those loop invariants isn't done
before the loop anymore, we have one extra multiplication on each
loop iteration instead. Sadly, this results in a significant
performance hit.
Similarly, specifically crafted user code will also experience
inability to hoist those invariants.
This patch is solving this issue by adding the ability to undo such
reassociation into the LICM pass. Note that for doing such
transformation this pass requires the same conditions as the
"Reassociate expressions" pass, namely, the involved binary operators
must have the reassociations allowed (e.g. by specifying the `fast`
attribute) and they must have single use only.
Some parts of this patch were suggested by Nikita Popov.
Reviewed By: huntergr, nikic, paulwalker-arm
Differential Revision: https://reviews.llvm.org/D152281
1399 lines
89 KiB
LLVM
1399 lines
89 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: opt -passes='reassociate' -S < %s | FileCheck %s --check-prefix=REASSOCIATE_ONLY
|
|
; RUN: opt -passes='licm' -S < %s | FileCheck %s --check-prefix=LICM_ONLY
|
|
; RUN: opt -passes='licm' -licm-max-num-fp-reassociations=1 -S < %s | FileCheck %s --check-prefix=LICM_ONLY_CONSTRAINED
|
|
; RUN: opt -passes='reassociate,loop-mssa(licm)' -S < %s | FileCheck %s --check-prefix=LICM_AFTER_REASSOCIATE
|
|
; RUN: opt -passes='reassociate,loop-mssa(licm)' -licm-max-num-fp-reassociations=1 -S < %s | FileCheck %s --check-prefix=LICM_AFTER_REASSOCIATE_CONSTRAINED
|
|
|
|
;
|
|
; A simple loop, should not get modified:
|
|
;
|
|
; int j;
|
|
; const double d1d = d1 * delta;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = d1d * cells[j + 1];
|
|
;
|
|
|
|
define void @innermost_loop_1d_fast(i32 %i, double %d1, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_1d_fast
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_1d_fast
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_1d_fast
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_1d_fast
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_1d_fast
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[DELTA]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%fmul.d1 = fmul fast double %d1, %delta
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul fast double %fmul.d1, %cell.1
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
store double %fmul.1, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; A simple loop:
|
|
;
|
|
; int j;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = d1 * cells[j + 1] * delta;
|
|
;
|
|
; ...should be transformed by the LICM pass into this:
|
|
;
|
|
; int j;
|
|
; const double d1d = d1 * delta;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = d1d * cells[j + 1];
|
|
;
|
|
|
|
define void @innermost_loop_1d_shouldhoist_fast(i32 %i, double %d1, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_1d_shouldhoist_fast
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_1d_shouldhoist_fast
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FACTOR_OP_FMUL]], [[CELL_1]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_1d_shouldhoist_fast
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FACTOR_OP_FMUL]], [[CELL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[FMUL_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_1d_shouldhoist_fast
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_1d_shouldhoist_fast
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[DELTA]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[FMUL_2]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul fast double %d1, %cell.1
|
|
%fmul.2 = fmul fast double %fmul.1, %delta
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
store double %fmul.2, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; The following loop will be modified by the 'Reassociate expressions' pass,
|
|
;
|
|
; int j;
|
|
; const double d1d = d1 * delta;
|
|
; const double d2d = d2 * delta;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = d1d * cells[j + 1] + d2d * cells[j];
|
|
;
|
|
; ...into this:
|
|
;
|
|
; int j;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;
|
|
;
|
|
; We expect the LICM pass to undo this transformation.
|
|
;
|
|
|
|
define void @innermost_loop_2d_fast(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_fast
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_2d_fast
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_ONLY-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_ONLY-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_fast
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%fmul.d1 = fmul fast double %d1, %delta
|
|
%fmul.d2 = fmul fast double %d2, %delta
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul fast double %fmul.d1, %cell.1
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
%cell.2 = load double, ptr %arrayidx.j, align 8
|
|
%fmul.2 = fmul fast double %fmul.d2, %cell.2
|
|
%fadd.1 = fadd fast double %fmul.1, %fmul.2
|
|
store double %fadd.1, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; The following loop will be modified by the 'Reassociate expressions' pass,
|
|
;
|
|
; int j;
|
|
; const double d1d = d1 * delta;
|
|
; const double d2d = d2 * delta;
|
|
; const double d3d = d3 * delta;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = d1d * cells[j + 1] + d2d * cells[j] + d3d * cells[j + 2];
|
|
;
|
|
; ...into this:
|
|
;
|
|
; int j;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = (d1 * cells[j + 1] + d2 * cells[j] + d3 * cells[j + 2]) * delta;
|
|
;
|
|
; We expect the LICM pass to undo this transformation.
|
|
;
|
|
|
|
|
|
define void @innermost_loop_3d_fast(i32 %i, double %d1, double %d2, double %d3, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_3d_fast
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[D3]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD1]], [[DELTA]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J_2]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_3d_fast
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: [[FMUL_D3:%.*]] = fmul fast double [[D3]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_ONLY-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_ONLY-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_3:%.*]] = fmul fast double [[FMUL_D3]], [[CELL_3]]
|
|
; LICM_ONLY-NEXT: [[FADD_2:%.*]] = fadd fast double [[FADD_1]], [[FMUL_3]]
|
|
; LICM_ONLY-NEXT: store double [[FADD_2]], ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D3:%.*]] = fmul fast double [[D3]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd fast double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_3:%.*]] = fmul fast double [[FMUL_D3]], [[CELL_3]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_2:%.*]] = fadd fast double [[FADD_1]], [[FMUL_3]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[FADD_2]], ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_3d_fast
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D3]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL2:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL3:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL3]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[FACTOR_OP_FMUL]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_ADD1]], ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_2:%.*]] = add nuw nsw i32 [[J]], 2
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_2]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_3:%.*]] = fmul fast double [[CELL_3]], [[D3]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD1:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_3]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD1]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%fmul.d1 = fmul fast double %d1, %delta
|
|
%fmul.d2 = fmul fast double %d2, %delta
|
|
%fmul.d3 = fmul fast double %d3, %delta
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul fast double %fmul.d1, %cell.1
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
%cell.2 = load double, ptr %arrayidx.j, align 8
|
|
%fmul.2 = fmul fast double %fmul.d2, %cell.2
|
|
%fadd.1 = fadd fast double %fmul.1, %fmul.2
|
|
%add.j.2 = add nuw nsw i32 %j, 2
|
|
%idxprom.j.2 = zext i32 %add.j.2 to i64
|
|
%arrayidx.j.2 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.2
|
|
%cell.3 = load double, ptr %arrayidx.j.2, align 8
|
|
%fmul.3 = fmul fast double %fmul.d3, %cell.3
|
|
%fadd.2 = fadd fast double %fadd.1, %fmul.3
|
|
store double %fadd.2, ptr %arrayidx.j.2, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; When there is no 'fast' attribute, the transformation should not happen.
|
|
;
|
|
|
|
define void @innermost_loop_2d_nofast(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nofast
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_2d_nofast
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_ONLY-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_ONLY-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nofast
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_D1:%.*]] = fmul double [[D1]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_D2:%.*]] = fmul double [[D2]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[FMUL_D1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[FMUL_D2]], [[CELL_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FADD_1:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[FADD_1]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%fmul.d1 = fmul double %d1, %delta
|
|
%fmul.d2 = fmul double %d2, %delta
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul double %fmul.d1, %cell.1
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
%cell.2 = load double, ptr %arrayidx.j, align 8
|
|
%fmul.2 = fmul double %fmul.d2, %cell.2
|
|
%fadd.1 = fadd double %fmul.1, %fmul.2
|
|
store double %fadd.1, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; The following loop should be modified by the LICM pass,
|
|
;
|
|
; int j;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;
|
|
;
|
|
; ...into this:
|
|
;
|
|
; int j;
|
|
; const double d1d = d1 * delta;
|
|
; const double d2d = d2 * delta;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = d1d * cells[j + 1] + d2d * cells[j];
|
|
;
|
|
|
|
define void @innermost_loop_2d_fast_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_fast_reassociated
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_2d_fast_reassociated
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]
|
|
; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_ONLY-NEXT: store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast_reassociated
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_fast_reassociated
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL:%.*]] = fmul fast double [[D1]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FACTOR_OP_FMUL1:%.*]] = fmul fast double [[D2]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[FACTOR_OP_FMUL]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[FACTOR_OP_FMUL1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_ADD]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_fast_reassociated
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_2]], [[D2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[REASS_ADD]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul fast double %cell.1, %d1
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
%cell.2 = load double, ptr %arrayidx.j, align 8
|
|
%fmul.2 = fmul fast double %cell.2, %d2
|
|
%reass.add = fadd fast double %fmul.2, %fmul.1
|
|
%reass.mul = fmul fast double %reass.add, %delta
|
|
store double %reass.mul, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; When there is no 'fast' attribute, the transformation should not happen.
|
|
;
|
|
|
|
define void @innermost_loop_2d_nofast_reassociated(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_2d_nofast_reassociated
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_2d_nofast_reassociated
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul double [[CELL_1]], [[D1]]
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul double [[CELL_2]], [[D2]]
|
|
; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul double [[REASS_ADD]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast_reassociated
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[CELL_1]], [[D1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[CELL_2]], [[D2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul double [[REASS_ADD]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_2d_nofast_reassociated
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_2d_nofast_reassociated
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul double [[D1]], [[CELL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul double [[D2]], [[CELL_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd double [[FMUL_1]], [[FMUL_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul double [[DELTA]], [[REASS_ADD]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%fmul.1 = fmul double %cell.1, %d1
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
%cell.2 = load double, ptr %arrayidx.j, align 8
|
|
%fmul.2 = fmul double %cell.2, %d2
|
|
%reass.add = fadd double %fmul.2, %fmul.1
|
|
%reass.mul = fmul double %reass.add, %delta
|
|
store double %reass.mul, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; The following loop will not be modified by the LICM pass:
|
|
;
|
|
; int j;
|
|
;
|
|
; for (j = 0; j <= i; j++)
|
|
; cells[j] = (d1 * cells[j + 1] + d2 * cells[j] +
|
|
; cells[j] * cells[j + 1]) * delta;
|
|
;
|
|
; This case differs as one of the multiplications involves no invariants.
|
|
;
|
|
|
|
define void @innermost_loop_3d_fast_reassociated_different(i32 %i, double %d1, double %d2, double %delta, ptr %cells) {
|
|
; REASSOCIATE_ONLY-LABEL: define void @innermost_loop_3d_fast_reassociated_different
|
|
; REASSOCIATE_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; REASSOCIATE_ONLY-NEXT: entry:
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; REASSOCIATE_ONLY: for.cond:
|
|
; REASSOCIATE_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; REASSOCIATE_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; REASSOCIATE_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; REASSOCIATE_ONLY: for.body:
|
|
; REASSOCIATE_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J_3:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; REASSOCIATE_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; REASSOCIATE_ONLY-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]
|
|
; REASSOCIATE_ONLY-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]
|
|
; REASSOCIATE_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
|
|
; REASSOCIATE_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; REASSOCIATE_ONLY-NEXT: br label [[FOR_COND]]
|
|
; REASSOCIATE_ONLY: for.end:
|
|
; REASSOCIATE_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY-LABEL: define void @innermost_loop_3d_fast_reassociated_different
|
|
; LICM_ONLY-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY-NEXT: entry:
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY: for.cond:
|
|
; LICM_ONLY-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY: for.body:
|
|
; LICM_ONLY-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_ONLY-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_ONLY-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
|
|
; LICM_ONLY-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_ONLY-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
|
|
; LICM_ONLY-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[REASS_ADD]]
|
|
; LICM_ONLY-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
|
|
; LICM_ONLY-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY: for.end:
|
|
; LICM_ONLY-NEXT: ret void
|
|
;
|
|
; LICM_ONLY_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast_reassociated_different
|
|
; LICM_ONLY_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_ONLY_CONSTRAINED-NEXT: entry:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_ONLY_CONSTRAINED: for.cond:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_ONLY_CONSTRAINED: for.body:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[FMUL_2]], [[FMUL_1]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[REASS_ADD]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
|
|
; LICM_ONLY_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_ONLY_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_ONLY_CONSTRAINED: for.end:
|
|
; LICM_ONLY_CONSTRAINED-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE-LABEL: define void @innermost_loop_3d_fast_reassociated_different
|
|
; LICM_AFTER_REASSOCIATE-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE: for.cond:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE: for.body:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE: for.end:
|
|
; LICM_AFTER_REASSOCIATE-NEXT: ret void
|
|
;
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-LABEL: define void @innermost_loop_3d_fast_reassociated_different
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-SAME: (i32 [[I:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[DELTA:%.*]], ptr [[CELLS:%.*]]) {
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: entry:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND:%.*]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.cond:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD_J_1:%.*]], [[FOR_BODY:%.*]] ]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[J]], [[I]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.body:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ADD_J_1]] = add nuw nsw i32 [[J]], 1
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_1:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_1:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_1:%.*]] = load double, ptr [[ARRAYIDX_J_1]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J_2:%.*]] = zext i32 [[ADD_J_1]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J_2:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_2:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_3:%.*]] = load double, ptr [[ARRAYIDX_J_2]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[IDXPROM_J:%.*]] = zext i32 [[J]] to i64
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[ARRAYIDX_J:%.*]] = getelementptr inbounds double, ptr [[CELLS]], i64 [[IDXPROM_J]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[CELL_4:%.*]] = load double, ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_1:%.*]] = fmul fast double [[CELL_1]], [[D1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[FMUL_2:%.*]] = fmul fast double [[CELL_4]], [[D2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[EXTRA_MUL:%.*]] = fmul fast double [[CELL_3]], [[CELL_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_ADD:%.*]] = fadd fast double [[EXTRA_MUL]], [[FMUL_1]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[EXTRA_ADD:%.*]] = fadd fast double [[REASS_ADD]], [[FMUL_2]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: [[REASS_MUL:%.*]] = fmul fast double [[EXTRA_ADD]], [[DELTA]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: store double [[REASS_MUL]], ptr [[ARRAYIDX_J]], align 8
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: br label [[FOR_COND]]
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED: for.end:
|
|
; LICM_AFTER_REASSOCIATE_CONSTRAINED-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%j = phi i32 [ 0, %entry ], [ %add.j.1, %for.body ]
|
|
%cmp.not = icmp sgt i32 %j, %i
|
|
br i1 %cmp.not, label %for.end, label %for.body
|
|
|
|
for.body:
|
|
%add.j.1 = add nuw nsw i32 %j, 1
|
|
%idxprom.j.1 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.1 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.1
|
|
%cell.1 = load double, ptr %arrayidx.j.1, align 8
|
|
%add.j.2 = add nuw nsw i32 %j, 2
|
|
%idxprom.j.2 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.2 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.2
|
|
%cell.2 = load double, ptr %arrayidx.j.2, align 8
|
|
%add.j.3 = add nuw nsw i32 %j, 3
|
|
%idxprom.j.3 = zext i32 %add.j.1 to i64
|
|
%arrayidx.j.3 = getelementptr inbounds double, ptr %cells, i64 %idxprom.j.3
|
|
%cell.3 = load double, ptr %arrayidx.j.2, align 8
|
|
%idxprom.j = zext i32 %j to i64
|
|
%arrayidx.j = getelementptr inbounds double, ptr %cells, i64 %idxprom.j
|
|
%cell.4 = load double, ptr %arrayidx.j, align 8
|
|
%fmul.1 = fmul fast double %cell.1, %d1
|
|
%fmul.2 = fmul fast double %cell.4, %d2
|
|
%reass.add = fadd fast double %fmul.2, %fmul.1
|
|
%extra.mul = fmul fast double %cell.3, %cell.2
|
|
%extra.add = fadd fast double %extra.mul, %reass.add
|
|
%reass.mul = fmul fast double %extra.add, %delta
|
|
store double %reass.mul, ptr %arrayidx.j, align 8
|
|
br label %for.cond
|
|
|
|
for.end:
|
|
ret void
|
|
}
|