|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| 2 | +; RUN: opt < %s -S -passes=instcombine -instcombine-enhanced-phi-cse=true | FileCheck %s |
| 3 | +@A = extern_weak global float, align 4 |
| 4 | + |
| 5 | +; %phi.to.remove acts the same as %v1, and can be eliminated with PHI CSE. |
| 6 | +define void @enhanced_phi_cse(ptr %m, ptr %n, i32 %count) { |
| 7 | +; CHECK-LABEL: @enhanced_phi_cse( |
| 8 | +; CHECK-NEXT: entry: |
| 9 | +; CHECK-NEXT: br label [[FOR_BODY:%.*]] |
| 10 | +; CHECK: for.body: |
| 11 | +; CHECK-NEXT: [[V0:%.*]] = phi float [ 0x4415AF1D80000000, [[ENTRY:%.*]] ], [ [[V0_1:%.*]], [[FOR_BODY]] ] |
| 12 | +; CHECK-NEXT: [[V1:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[V1_1:%.*]], [[FOR_BODY]] ] |
| 13 | +; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC_I:%.*]], [[FOR_BODY]] ] |
| 14 | +; CHECK-NEXT: [[Q:%.*]] = phi ptr [ [[M:%.*]], [[ENTRY]] ], [ [[Q_NEXT:%.*]], [[FOR_BODY]] ] |
| 15 | +; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[N:%.*]], [[ENTRY]] ], [ [[C_NEXT:%.*]], [[FOR_BODY]] ] |
| 16 | +; CHECK-NEXT: [[Q_LOAD:%.*]] = load float, ptr [[Q]], align 4 |
| 17 | +; CHECK-NEXT: [[C_LOAD:%.*]] = load float, ptr [[C]], align 4 |
| 18 | +; CHECK-NEXT: [[SUB:%.*]] = fsub float [[Q_LOAD]], [[C_LOAD]] |
| 19 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[SUB]], [[V0]] |
| 20 | +; CHECK-NEXT: [[V0_1]] = select i1 [[CMP1]], float [[SUB]], float [[V0]] |
| 21 | +; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[SUB]], [[V1]] |
| 22 | +; CHECK-NEXT: [[V1_1]] = select i1 [[CMP2]], float [[SUB]], float [[V1]] |
| 23 | +; CHECK-NEXT: [[INC_I]] = add nuw nsw i32 [[I]], 1 |
| 24 | +; CHECK-NEXT: [[Q_NEXT]] = getelementptr inbounds float, ptr [[Q]], i64 1 |
| 25 | +; CHECK-NEXT: [[C_NEXT]] = getelementptr inbounds float, ptr [[C]], i64 1 |
| 26 | +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC_I]], [[COUNT:%.*]] |
| 27 | +; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[FOR_BODY]] |
| 28 | +; CHECK: exit: |
| 29 | +; CHECK-NEXT: store float [[V1_1]], ptr @A, align 4 |
| 30 | +; CHECK-NEXT: ret void |
| 31 | +; |
| 32 | +entry: |
| 33 | + br label %for.body |
| 34 | + |
| 35 | +for.body: ; preds = %entry, %for.body |
| 36 | + %v0 = phi float [ 0x4415AF1D80000000, %entry ], [ %v0.1, %for.body ] |
| 37 | + %v1 = phi float [ 0xC415AF1D80000000, %entry ], [ %v1.1, %for.body ] |
| 38 | + %phi.to.remove = phi float [ 0xC415AF1D80000000, %entry ], [ %phi.to.remove.next, %for.body ] |
| 39 | + %i = phi i32 [ 0, %entry ], [ %inc.i, %for.body ] |
| 40 | + %q = phi ptr [ %m, %entry ], [ %q.next, %for.body ] |
| 41 | + %c = phi ptr [ %n, %entry ], [ %c.next, %for.body ] |
| 42 | + %q.load = load float, ptr %q |
| 43 | + %c.load = load float, ptr %c |
| 44 | + %sub = fsub float %q.load, %c.load |
| 45 | + %cmp1 = fcmp olt float %sub, %v0 |
| 46 | + %v0.1 = select i1 %cmp1, float %sub, float %v0 |
| 47 | + %same.as.v1 = select i1 %cmp1, float %v1, float %phi.to.remove |
| 48 | + %cmp2 = fcmp ogt float %sub, %same.as.v1 |
| 49 | + %v1.1 = select i1 %cmp2, float %sub, float %v1 |
| 50 | + %phi.to.remove.next = select i1 %cmp2, float %sub, float %same.as.v1 |
| 51 | + %inc.i = add nuw nsw i32 %i, 1 |
| 52 | + %q.next = getelementptr inbounds float, ptr %q, i64 1 |
| 53 | + %c.next = getelementptr inbounds float, ptr %c, i64 1 |
| 54 | + %exitcond = icmp eq i32 %inc.i, %count |
| 55 | + br i1 %exitcond, label %exit, label %for.body |
| 56 | + |
| 57 | +exit: |
| 58 | + %vl.1.lcssa = phi float [ %v1.1, %for.body ] |
| 59 | + store float %vl.1.lcssa, ptr @A |
| 60 | + ret void |
| 61 | +} |
0 commit comments