Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,21 +233,22 @@ static Value *getValueOnEdge(LazyValueInfo *LVI, Value *Incoming,
// value can never be that constant. In that case replace the incoming
// value with the other value of the select. This often allows us to
// remove the select later.
if (!SI->getType()->isFPOrFPVectorTy()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better to make it an isIntOrIntVectorTy. Does this handle the pointer case below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also handles the pointer case. See also Transforms/CorrelatedValuePropagation/basic.ll:


; "true" case for CorrelatedValuePropagation
define void @loop2(ptr %x, ptr %y) {
; CHECK-LABEL: define void @loop2
; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
; CHECK-NEXT:  entry:
; CHECK-NEXT:    br label [[LOOP:%.*]]
; CHECK:       loop:
; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[F]] = tail call ptr @f(ptr [[PHI]])
; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq ptr [[F]], [[Y]]
; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], ptr null, ptr [[F]]
; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
; CHECK:       return:
; CHECK-NEXT:    ret void
;
entry:
  br label %loop

loop:
  %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
  %f = tail call ptr @f(ptr %phi)
  %cmp1 = icmp eq ptr %f, %y
  %sel = select i1 %cmp1, ptr null, ptr %f
  %cmp2 = icmp eq ptr %sel, null
  br i1 %cmp2, label %return, label %loop

return:
  ret void
}

// The "false" case
if (auto *C = dyn_cast<Constant>(SI->getFalseValue()))
if (auto *Res = dyn_cast_or_null<ConstantInt>(LVI->getPredicateOnEdge(
ICmpInst::ICMP_EQ, SI, C, From, To, CxtI));
Res && Res->isZero())
return SI->getTrueValue();

// The "false" case
if (auto *C = dyn_cast<Constant>(SI->getFalseValue()))
if (auto *Res = dyn_cast_or_null<ConstantInt>(
LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, From, To, CxtI));
Res && Res->isZero())
return SI->getTrueValue();

// The "true" case,
// similar to the select "false" case, but try the select "true" value
if (auto *C = dyn_cast<Constant>(SI->getTrueValue()))
if (auto *Res = dyn_cast_or_null<ConstantInt>(
LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, From, To, CxtI));
Res && Res->isZero())
return SI->getFalseValue();
// The "true" case,
// similar to the select "false" case, but try the select "true" value
if (auto *C = dyn_cast<Constant>(SI->getTrueValue()))
if (auto *Res = dyn_cast_or_null<ConstantInt>(LVI->getPredicateOnEdge(
ICmpInst::ICMP_EQ, SI, C, From, To, CxtI));
Res && Res->isZero())
return SI->getFalseValue();
}

return nullptr;
}
Expand Down