Skip to content

Commit c01fb33

Browse files
Address comments made on Oct 22nd.
1 parent 4d8a564 commit c01fb33

File tree

2 files changed

+249
-3
lines changed

2 files changed

+249
-3
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4895,7 +4895,7 @@ static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F,
48954895
/// is false and %to_fold is %phi, which contradicts our inductive hypothesis
48964896
/// that %phi and %identicalPhi are equal. Thus %phi and %identicalPhi are
48974897
/// always equal at iteration i+1.
4898-
bool isSimplifierIdenticalPHI(PHINode &PN, PHINode &IdenticalPN) {
4898+
bool isSelectWithIdenticalPHI(PHINode &PN, PHINode &IdenticalPN) {
48994899
if (PN.getParent() != IdenticalPN.getParent())
49004900
return false;
49014901
if (PN.getNumIncomingValues() != 2)
@@ -5127,9 +5127,9 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
51275127
// Look for same PHIs in the true and false values.
51285128
if (auto *TruePHI = dyn_cast<PHINode>(TrueVal))
51295129
if (auto *FalsePHI = dyn_cast<PHINode>(FalseVal)) {
5130-
if (isSimplifierIdenticalPHI(*TruePHI, *FalsePHI))
5130+
if (isSelectWithIdenticalPHI(*TruePHI, *FalsePHI))
51315131
return FalseVal;
5132-
if (isSimplifierIdenticalPHI(*FalsePHI, *TruePHI))
5132+
if (isSelectWithIdenticalPHI(*FalsePHI, *TruePHI))
51335133
return TrueVal;
51345134
}
51355135
return nullptr;

llvm/test/Transforms/InstCombine/select_with_identical_phi.ll

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,249 @@ exit:
241241
store float %vl.1.lcssa, ptr @A
242242
ret void
243243
}
244+
245+
; The difference from select_with_identical_phi() is that not all phis are sorted with
246+
; the same order of incoming BBs.
247+
; Check that %same.as.v1 can be folded.
248+
define void @select_with_identical_phi_5(ptr %m, ptr %n, i32 %count) {
249+
; CHECK-LABEL: @select_with_identical_phi_5(
250+
; CHECK-NEXT: entry:
251+
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
252+
; CHECK: for.body:
253+
; CHECK-NEXT: [[V0:%.*]] = phi float [ 0x4415AF1D80000000, [[ENTRY:%.*]] ], [ [[V0_1:%.*]], [[FOR_BODY]] ]
254+
; CHECK-NEXT: [[V1:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[V1_1:%.*]], [[FOR_BODY]] ]
255+
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC_I:%.*]], [[FOR_BODY]] ]
256+
; CHECK-NEXT: [[Q:%.*]] = phi ptr [ [[M:%.*]], [[ENTRY]] ], [ [[Q_NEXT:%.*]], [[FOR_BODY]] ]
257+
; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[N:%.*]], [[ENTRY]] ], [ [[C_NEXT:%.*]], [[FOR_BODY]] ]
258+
; CHECK-NEXT: [[Q_LOAD:%.*]] = load float, ptr [[Q]], align 4
259+
; CHECK-NEXT: [[C_LOAD:%.*]] = load float, ptr [[C]], align 4
260+
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[Q_LOAD]], [[C_LOAD]]
261+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[SUB]], [[V0]]
262+
; CHECK-NEXT: [[V0_1]] = select i1 [[CMP1]], float [[SUB]], float [[V0]]
263+
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[SUB]], [[V1]]
264+
; CHECK-NEXT: [[V1_1]] = select i1 [[CMP2]], float [[SUB]], float [[V1]]
265+
; CHECK-NEXT: [[INC_I]] = add nuw nsw i32 [[I]], 1
266+
; CHECK-NEXT: [[Q_NEXT]] = getelementptr inbounds nuw i8, ptr [[Q]], i64 4
267+
; CHECK-NEXT: [[C_NEXT]] = getelementptr inbounds nuw i8, ptr [[C]], i64 4
268+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC_I]], [[COUNT:%.*]]
269+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[FOR_BODY]]
270+
; CHECK: exit:
271+
; CHECK-NEXT: store float [[V1_1]], ptr @A, align 4
272+
; CHECK-NEXT: ret void
273+
;
274+
entry:
275+
br label %for.body
276+
277+
for.body: ; preds = %entry, %for.body
278+
%v0 = phi float [ 0x4415AF1D80000000, %entry ], [ %v0.1, %for.body ]
279+
%v1 = phi float [ 0xC415AF1D80000000, %entry ], [ %v1.1, %for.body ]
280+
%phi.to.remove = phi float [ %phi.to.remove.next, %for.body ], [ 0xC415AF1D80000000, %entry ]
281+
%i = phi i32 [ 0, %entry ], [ %inc.i, %for.body ]
282+
%q = phi ptr [ %m, %entry ], [ %q.next, %for.body ]
283+
%c = phi ptr [ %n, %entry ], [ %c.next, %for.body ]
284+
%q.load = load float, ptr %q
285+
%c.load = load float, ptr %c
286+
%sub = fsub float %q.load, %c.load
287+
%cmp1 = fcmp olt float %sub, %v0
288+
%v0.1 = select i1 %cmp1, float %sub, float %v0
289+
%same.as.v1 = select i1 %cmp1, float %v1, float %phi.to.remove
290+
%cmp2 = fcmp ogt float %sub, %same.as.v1
291+
%v1.1 = select i1 %cmp2, float %sub, float %v1
292+
%phi.to.remove.next = select i1 %cmp2, float %sub, float %same.as.v1
293+
%inc.i = add nuw nsw i32 %i, 1
294+
%q.next = getelementptr inbounds i8, ptr %q, i64 4
295+
%c.next = getelementptr inbounds i8, ptr %c, i64 4
296+
%exitcond = icmp eq i32 %inc.i, %count
297+
br i1 %exitcond, label %exit, label %for.body
298+
299+
exit:
300+
%vl.1.lcssa = phi float [ %v1.1, %for.body ]
301+
store float %vl.1.lcssa, ptr @A
302+
ret void
303+
}
304+
305+
; %v1 and %phi.to.remove do not have the same start value.
306+
; Cannot fold %same.as.v1.
307+
define void @select_with_identical_phi_negative_1(ptr %m, ptr %n, i32 %count) {
308+
; CHECK-LABEL: @select_with_identical_phi_negative_1(
309+
; CHECK-NEXT: entry:
310+
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
311+
; CHECK: for.body:
312+
; CHECK-NEXT: [[V0:%.*]] = phi float [ 0x4415AF1D80000000, [[ENTRY:%.*]] ], [ [[V0_1:%.*]], [[FOR_BODY]] ]
313+
; CHECK-NEXT: [[V1:%.*]] = phi float [ 0x4415AF1D80000000, [[ENTRY]] ], [ [[V1_1:%.*]], [[FOR_BODY]] ]
314+
; CHECK-NEXT: [[PHI_TO_REMOVE:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[PHI_TO_REMOVE_NEXT:%.*]], [[FOR_BODY]] ]
315+
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC_I:%.*]], [[FOR_BODY]] ]
316+
; CHECK-NEXT: [[Q:%.*]] = phi ptr [ [[M:%.*]], [[ENTRY]] ], [ [[Q_NEXT:%.*]], [[FOR_BODY]] ]
317+
; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[N:%.*]], [[ENTRY]] ], [ [[C_NEXT:%.*]], [[FOR_BODY]] ]
318+
; CHECK-NEXT: [[Q_LOAD:%.*]] = load float, ptr [[Q]], align 4
319+
; CHECK-NEXT: [[C_LOAD:%.*]] = load float, ptr [[C]], align 4
320+
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[Q_LOAD]], [[C_LOAD]]
321+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[SUB]], [[V0]]
322+
; CHECK-NEXT: [[V0_1]] = select i1 [[CMP1]], float [[SUB]], float [[V0]]
323+
; CHECK-NEXT: [[SAME_AS_V1:%.*]] = select i1 [[CMP1]], float [[V1]], float [[PHI_TO_REMOVE]]
324+
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[SUB]], [[SAME_AS_V1]]
325+
; CHECK-NEXT: [[V1_1]] = select i1 [[CMP2]], float [[SUB]], float [[V1]]
326+
; CHECK-NEXT: [[PHI_TO_REMOVE_NEXT]] = select i1 [[CMP2]], float [[SUB]], float [[SAME_AS_V1]]
327+
; CHECK-NEXT: [[INC_I]] = add nuw nsw i32 [[I]], 1
328+
; CHECK-NEXT: [[Q_NEXT]] = getelementptr inbounds nuw i8, ptr [[Q]], i64 4
329+
; CHECK-NEXT: [[C_NEXT]] = getelementptr inbounds nuw i8, ptr [[C]], i64 4
330+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC_I]], [[COUNT:%.*]]
331+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[FOR_BODY]]
332+
; CHECK: exit:
333+
; CHECK-NEXT: store float [[V1_1]], ptr @A, align 4
334+
; CHECK-NEXT: ret void
335+
;
336+
entry:
337+
br label %for.body
338+
339+
for.body: ; preds = %entry, %for.body
340+
%v0 = phi float [ 0x4415AF1D80000000, %entry ], [ %v0.1, %for.body ]
341+
%v1 = phi float [ 0x4415AF1D80000000, %entry ], [ %v1.1, %for.body ]
342+
%phi.to.remove = phi float [ 0xC415AF1D80000000, %entry ], [ %phi.to.remove.next, %for.body ]
343+
%i = phi i32 [ 0, %entry ], [ %inc.i, %for.body ]
344+
%q = phi ptr [ %m, %entry ], [ %q.next, %for.body ]
345+
%c = phi ptr [ %n, %entry ], [ %c.next, %for.body ]
346+
%q.load = load float, ptr %q
347+
%c.load = load float, ptr %c
348+
%sub = fsub float %q.load, %c.load
349+
%cmp1 = fcmp olt float %sub, %v0
350+
%v0.1 = select i1 %cmp1, float %sub, float %v0
351+
%same.as.v1 = select i1 %cmp1, float %v1, float %phi.to.remove
352+
%cmp2 = fcmp ogt float %sub, %same.as.v1
353+
%v1.1 = select i1 %cmp2, float %sub, float %v1
354+
%phi.to.remove.next = select i1 %cmp2, float %sub, float %same.as.v1
355+
%inc.i = add nuw nsw i32 %i, 1
356+
%q.next = getelementptr inbounds i8, ptr %q, i64 4
357+
%c.next = getelementptr inbounds i8, ptr %c, i64 4
358+
%exitcond = icmp eq i32 %inc.i, %count
359+
br i1 %exitcond, label %exit, label %for.body
360+
361+
exit:
362+
%vl.1.lcssa = phi float [ %v1.1, %for.body ]
363+
store float %vl.1.lcssa, ptr @A
364+
ret void
365+
}
366+
367+
; %v1 and %phi.to.remove do not act as the same phi since %v1.1 and %phi.to.remove.next do not evolve the same.
368+
; Cannot fold %same.as.v1.
369+
define void @select_with_identical_phi_negative_2(ptr %m, ptr %n, i32 %count) {
370+
; CHECK-LABEL: @select_with_identical_phi_negative_2(
371+
; CHECK-NEXT: entry:
372+
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
373+
; CHECK: for.body:
374+
; CHECK-NEXT: [[V0:%.*]] = phi float [ 0x4415AF1D80000000, [[ENTRY:%.*]] ], [ [[V0_1:%.*]], [[FOR_BODY]] ]
375+
; CHECK-NEXT: [[V1:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[V1_1:%.*]], [[FOR_BODY]] ]
376+
; CHECK-NEXT: [[PHI_TO_REMOVE:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[PHI_TO_REMOVE_NEXT:%.*]], [[FOR_BODY]] ]
377+
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC_I:%.*]], [[FOR_BODY]] ]
378+
; CHECK-NEXT: [[Q:%.*]] = phi ptr [ [[M:%.*]], [[ENTRY]] ], [ [[Q_NEXT:%.*]], [[FOR_BODY]] ]
379+
; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[N:%.*]], [[ENTRY]] ], [ [[C_NEXT:%.*]], [[FOR_BODY]] ]
380+
; CHECK-NEXT: [[Q_LOAD:%.*]] = load float, ptr [[Q]], align 4
381+
; CHECK-NEXT: [[C_LOAD:%.*]] = load float, ptr [[C]], align 4
382+
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[Q_LOAD]], [[C_LOAD]]
383+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[SUB]], [[V0]]
384+
; CHECK-NEXT: [[V0_1]] = select i1 [[CMP1]], float [[SUB]], float [[V0]]
385+
; CHECK-NEXT: [[SAME_AS_V1:%.*]] = select i1 [[CMP1]], float [[V1]], float [[PHI_TO_REMOVE]]
386+
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[SUB]], [[SAME_AS_V1]]
387+
; CHECK-NEXT: [[V1_1]] = select i1 [[CMP2]], float [[V1]], float [[SUB]]
388+
; CHECK-NEXT: [[PHI_TO_REMOVE_NEXT]] = select i1 [[CMP2]], float [[SUB]], float [[SAME_AS_V1]]
389+
; CHECK-NEXT: [[INC_I]] = add nuw nsw i32 [[I]], 1
390+
; CHECK-NEXT: [[Q_NEXT]] = getelementptr inbounds nuw i8, ptr [[Q]], i64 4
391+
; CHECK-NEXT: [[C_NEXT]] = getelementptr inbounds nuw i8, ptr [[C]], i64 4
392+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC_I]], [[COUNT:%.*]]
393+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[FOR_BODY]]
394+
; CHECK: exit:
395+
; CHECK-NEXT: store float [[V1_1]], ptr @A, align 4
396+
; CHECK-NEXT: ret void
397+
;
398+
entry:
399+
br label %for.body
400+
401+
for.body: ; preds = %entry, %for.body
402+
%v0 = phi float [ 0x4415AF1D80000000, %entry ], [ %v0.1, %for.body ]
403+
%v1 = phi float [ 0xC415AF1D80000000, %entry ], [ %v1.1, %for.body ]
404+
%phi.to.remove = phi float [ 0xC415AF1D80000000, %entry ], [ %phi.to.remove.next, %for.body ]
405+
%i = phi i32 [ 0, %entry ], [ %inc.i, %for.body ]
406+
%q = phi ptr [ %m, %entry ], [ %q.next, %for.body ]
407+
%c = phi ptr [ %n, %entry ], [ %c.next, %for.body ]
408+
%q.load = load float, ptr %q
409+
%c.load = load float, ptr %c
410+
%sub = fsub float %q.load, %c.load
411+
%cmp1 = fcmp olt float %sub, %v0
412+
%v0.1 = select i1 %cmp1, float %sub, float %v0
413+
%same.as.v1 = select i1 %cmp1, float %v1, float %phi.to.remove
414+
%cmp2 = fcmp ogt float %sub, %same.as.v1
415+
%v1.1 = select i1 %cmp2, float %v1, float %sub
416+
%phi.to.remove.next = select i1 %cmp2, float %sub, float %same.as.v1
417+
%inc.i = add nuw nsw i32 %i, 1
418+
%q.next = getelementptr inbounds i8, ptr %q, i64 4
419+
%c.next = getelementptr inbounds i8, ptr %c, i64 4
420+
%exitcond = icmp eq i32 %inc.i, %count
421+
br i1 %exitcond, label %exit, label %for.body
422+
423+
exit:
424+
%vl.1.lcssa = phi float [ %v1.1, %for.body ]
425+
store float %vl.1.lcssa, ptr @A
426+
ret void
427+
}
428+
429+
; The true and false values of %same.as.v1 are not really the same phi.
430+
; Cannot fold %same.as.v1.
431+
define void @select_with_identical_phi_negative_3(ptr %m, ptr %n, i32 %count) {
432+
; CHECK-LABEL: @select_with_identical_phi_negative_3(
433+
; CHECK-NEXT: entry:
434+
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
435+
; CHECK: for.body:
436+
; CHECK-NEXT: [[V0:%.*]] = phi float [ 0x4415AF1D80000000, [[ENTRY:%.*]] ], [ [[V0_1:%.*]], [[FOR_BODY]] ]
437+
; CHECK-NEXT: [[V1:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[V1_1:%.*]], [[FOR_BODY]] ]
438+
; CHECK-NEXT: [[PHI_TO_REMOVE:%.*]] = phi float [ 0xC415AF1D80000000, [[ENTRY]] ], [ [[PHI_TO_REMOVE_NEXT:%.*]], [[FOR_BODY]] ]
439+
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC_I:%.*]], [[FOR_BODY]] ]
440+
; CHECK-NEXT: [[Q:%.*]] = phi ptr [ [[M:%.*]], [[ENTRY]] ], [ [[Q_NEXT:%.*]], [[FOR_BODY]] ]
441+
; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[N:%.*]], [[ENTRY]] ], [ [[C_NEXT:%.*]], [[FOR_BODY]] ]
442+
; CHECK-NEXT: [[Q_LOAD:%.*]] = load float, ptr [[Q]], align 4
443+
; CHECK-NEXT: [[C_LOAD:%.*]] = load float, ptr [[C]], align 4
444+
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[Q_LOAD]], [[C_LOAD]]
445+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[SUB]], [[V0]]
446+
; CHECK-NEXT: [[V0_1]] = select i1 [[CMP1]], float [[SUB]], float [[V0]]
447+
; CHECK-NEXT: [[SAME_AS_V1:%.*]] = select i1 [[CMP1]], float [[V0]], float [[PHI_TO_REMOVE]]
448+
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[SUB]], [[SAME_AS_V1]]
449+
; CHECK-NEXT: [[V1_1]] = select i1 [[CMP2]], float [[SUB]], float [[V1]]
450+
; CHECK-NEXT: [[PHI_TO_REMOVE_NEXT]] = select i1 [[CMP2]], float [[SUB]], float [[SAME_AS_V1]]
451+
; CHECK-NEXT: [[INC_I]] = add nuw nsw i32 [[I]], 1
452+
; CHECK-NEXT: [[Q_NEXT]] = getelementptr inbounds nuw i8, ptr [[Q]], i64 4
453+
; CHECK-NEXT: [[C_NEXT]] = getelementptr inbounds nuw i8, ptr [[C]], i64 4
454+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC_I]], [[COUNT:%.*]]
455+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[FOR_BODY]]
456+
; CHECK: exit:
457+
; CHECK-NEXT: store float [[V1_1]], ptr @A, align 4
458+
; CHECK-NEXT: ret void
459+
;
460+
entry:
461+
br label %for.body
462+
463+
for.body: ; preds = %entry, %for.body
464+
%v0 = phi float [ 0x4415AF1D80000000, %entry ], [ %v0.1, %for.body ]
465+
%v1 = phi float [ 0xC415AF1D80000000, %entry ], [ %v1.1, %for.body ]
466+
%phi.to.remove = phi float [ 0xC415AF1D80000000, %entry ], [ %phi.to.remove.next, %for.body ]
467+
%i = phi i32 [ 0, %entry ], [ %inc.i, %for.body ]
468+
%q = phi ptr [ %m, %entry ], [ %q.next, %for.body ]
469+
%c = phi ptr [ %n, %entry ], [ %c.next, %for.body ]
470+
%q.load = load float, ptr %q
471+
%c.load = load float, ptr %c
472+
%sub = fsub float %q.load, %c.load
473+
%cmp1 = fcmp olt float %sub, %v0
474+
%v0.1 = select i1 %cmp1, float %sub, float %v0
475+
%same.as.v1 = select i1 %cmp1, float %v0, float %phi.to.remove
476+
%cmp2 = fcmp ogt float %sub, %same.as.v1
477+
%v1.1 = select i1 %cmp2, float %sub, float %v1
478+
%phi.to.remove.next = select i1 %cmp2, float %sub, float %same.as.v1
479+
%inc.i = add nuw nsw i32 %i, 1
480+
%q.next = getelementptr inbounds i8, ptr %q, i64 4
481+
%c.next = getelementptr inbounds i8, ptr %c, i64 4
482+
%exitcond = icmp eq i32 %inc.i, %count
483+
br i1 %exitcond, label %exit, label %for.body
484+
485+
exit:
486+
%vl.1.lcssa = phi float [ %v1.1, %for.body ]
487+
store float %vl.1.lcssa, ptr @A
488+
ret void
489+
}

0 commit comments

Comments
 (0)