| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt %s -S -riscv-promote-const -mtriple=riscv64 -mattr=+d | FileCheck %s |
| |
| ; No promotion should take place, as the pass skips floats. |
| define float @multiple_floats(float %a, float %b) { |
| ; CHECK-LABEL: define float @multiple_floats( |
| ; CHECK-SAME: float [[A:%.*]], float [[B:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[ADD1:%.*]] = fadd float [[A]], 1.000000e+00 |
| ; CHECK-NEXT: [[ADD2:%.*]] = fadd float [[B]], 2.000000e+00 |
| ; CHECK-NEXT: [[SUM_F:%.*]] = fadd float [[ADD1]], [[ADD2]] |
| ; CHECK-NEXT: ret float [[SUM_F]] |
| ; |
| entry: |
| %add1 = fadd float %a, 1.0 |
| %add2 = fadd float %b, 2.0 |
| %sum_f = fadd float %add1, %add2 |
| ret float %sum_f |
| } |
| |
| ; No promotion should take place as cases with a single constant are skipped. |
| define double @single_double(double %a) { |
| ; CHECK-LABEL: define double @single_double( |
| ; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[ADD:%.*]] = fadd double [[A]], 4.210000e+01 |
| ; CHECK-NEXT: ret double [[ADD]] |
| ; |
| entry: |
| %add = fadd double %a, 42.1 |
| ret double %add |
| } |
| |
| ; Promotion should happen as we have at least two unique constants that would |
| ; otherwise go in the constant pool. |
| define double @multiple_doubles(double %a, double %b) { |
| ; CHECK-LABEL: define double @multiple_doubles( |
| ; CHECK-SAME: double [[A:%.*]], double [[B:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[DOUBLE_VAL1:%.*]] = load double, ptr getelementptr inbounds ([2 x double], ptr @.promoted_doubles.multiple_doubles, i64 0, i64 1), align 8 |
| ; CHECK-NEXT: [[ADD3:%.*]] = load double, ptr @.promoted_doubles.multiple_doubles, align 8 |
| ; CHECK-NEXT: [[ADD2:%.*]] = fadd double [[A]], [[ADD3]] |
| ; CHECK-NEXT: [[ADD4:%.*]] = fadd double [[B]], [[DOUBLE_VAL1]] |
| ; CHECK-NEXT: [[SUM:%.*]] = fadd double [[ADD2]], [[ADD3]] |
| ; CHECK-NEXT: [[SUM1:%.*]] = fadd double [[ADD4]], [[SUM]] |
| ; CHECK-NEXT: ret double [[SUM1]] |
| ; |
| entry: |
| %add1 = fadd double %a, 2.718 |
| %add2 = fadd double %b, 42.1 |
| %add3 = fadd double %add1, 2.718 |
| %sum = fadd double %add2, %add3 |
| ret double %sum |
| } |
| |
| ; Promotion should not happen as the constants will be materialised rather |
| ; than using the constant pool. |
| define double @multiple_doubles_no_promote(double %a, double %b) { |
| ; CHECK-LABEL: define double @multiple_doubles_no_promote( |
| ; CHECK-SAME: double [[A:%.*]], double [[B:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[ADD1:%.*]] = fadd double [[A]], 1.000000e+00 |
| ; CHECK-NEXT: [[ADD2:%.*]] = fadd double [[B]], 2.000000e+00 |
| ; CHECK-NEXT: [[ADD3:%.*]] = fadd double [[ADD1]], 1.000000e+00 |
| ; CHECK-NEXT: [[SUM:%.*]] = fadd double [[ADD2]], [[ADD3]] |
| ; CHECK-NEXT: ret double [[SUM]] |
| ; |
| entry: |
| %add1 = fadd double %a, 1.0 |
| %add2 = fadd double %b, 2.0 |
| %add3 = fadd double %add1, 1.0 |
| %sum = fadd double %add2, %add3 |
| ret double %sum |
| } |
| |
| ; The same constant shouldn't be loaded more than once per BB. |
| define double @multiple_doubles_multi_bb(double %a, i1 %cond) { |
| ; CHECK-LABEL: define double @multiple_doubles_multi_bb( |
| ; CHECK-SAME: double [[A:%.*]], i1 [[COND:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]] |
| ; CHECK: [[IF_TRUE]]: |
| ; CHECK-NEXT: [[DOUBLE_VAL2:%.*]] = load double, ptr getelementptr inbounds ([2 x double], ptr @.promoted_doubles.multiple_doubles_multi_bb, i64 0, i64 1), align 8 |
| ; CHECK-NEXT: [[DOUBLE_VAL:%.*]] = load double, ptr @.promoted_doubles.multiple_doubles_multi_bb, align 8 |
| ; CHECK-NEXT: [[ADD_T:%.*]] = fadd double [[A]], [[DOUBLE_VAL]] |
| ; CHECK-NEXT: [[MUL_T:%.*]] = fmul double [[ADD_T]], [[DOUBLE_VAL2]] |
| ; CHECK-NEXT: [[SUB_T:%.*]] = fsub double [[MUL_T]], [[DOUBLE_VAL]] |
| ; CHECK-NEXT: br label %[[IF_END:.*]] |
| ; CHECK: [[IF_FALSE]]: |
| ; CHECK-NEXT: [[DOUBLE_VAL3:%.*]] = load double, ptr getelementptr inbounds ([2 x double], ptr @.promoted_doubles.multiple_doubles_multi_bb, i64 0, i64 1), align 8 |
| ; CHECK-NEXT: [[DOUBLE_VAL1:%.*]] = load double, ptr @.promoted_doubles.multiple_doubles_multi_bb, align 8 |
| ; CHECK-NEXT: [[ADD_F:%.*]] = fadd double [[A]], [[DOUBLE_VAL1]] |
| ; CHECK-NEXT: [[MUL_F:%.*]] = fmul double [[ADD_F]], [[DOUBLE_VAL3]] |
| ; CHECK-NEXT: [[SUB_F:%.*]] = fsub double [[MUL_F]], [[DOUBLE_VAL1]] |
| ; CHECK-NEXT: br label %[[IF_END]] |
| ; CHECK: [[IF_END]]: |
| ; CHECK-NEXT: [[PHI_RES:%.*]] = phi double [ [[SUB_T]], %[[IF_TRUE]] ], [ [[SUB_F]], %[[IF_FALSE]] ] |
| ; CHECK-NEXT: ret double [[PHI_RES]] |
| ; |
| entry: |
| br i1 %cond, label %if.true, label %if.false |
| |
| if.true: |
| %add.t = fadd double %a, 1.23 |
| %mul.t = fmul double %add.t, 4.56 |
| %sub.t = fsub double %mul.t, 1.23 |
| br label %if.end |
| |
| if.false: |
| %add.f = fadd double %a, 1.23 |
| %mul.f = fmul double %add.f, 4.56 |
| %sub.f = fsub double %mul.f, 1.23 |
| br label %if.end |
| |
| if.end: |
| %phi.res = phi double [ %sub.t, %if.true ], [ %sub.f, %if.false ] |
| ret double %phi.res |
| } |
| |
| ; Check the insertion point in the case we have a phi taking a constant C and |
| ; the source block also uses that same constant. |
| define double @multiple_doubles_phi(double %a, i1 %cond) { |
| ; CHECK-LABEL: define double @multiple_doubles_phi( |
| ; CHECK-SAME: double [[A:%.*]], i1 [[COND:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] |
| ; CHECK: [[IF_THEN]]: |
| ; CHECK-NEXT: [[DOUBLE_VAL:%.*]] = load double, ptr @.promoted_doubles.multiple_doubles_phi, align 8 |
| ; CHECK-NEXT: [[MUL:%.*]] = fmul double [[A]], [[DOUBLE_VAL]] |
| ; CHECK-NEXT: br label %[[IF_END]] |
| ; CHECK: [[IF_END]]: |
| ; CHECK-NEXT: [[PHI_VAL:%.*]] = phi double [ [[DOUBLE_VAL]], %[[IF_THEN]] ], [ [[A]], %[[ENTRY]] ] |
| ; CHECK-NEXT: [[DOUBLE_VAL1:%.*]] = load double, ptr getelementptr inbounds ([2 x double], ptr @.promoted_doubles.multiple_doubles_phi, i64 0, i64 1), align 8 |
| ; CHECK-NEXT: [[RES:%.*]] = fadd double [[PHI_VAL]], [[DOUBLE_VAL1]] |
| ; CHECK-NEXT: ret double [[RES]] |
| ; |
| entry: |
| br i1 %cond, label %if.then, label %if.end |
| |
| if.then: |
| %mul = fmul double %a, 1.23 |
| br label %if.end |
| |
| if.end: |
| %phi.val = phi double [ 1.23, %if.then ], [ %a, %entry ] |
| %res = fadd double %phi.val, 4.56 |
| ret double %res |
| } |