<div dir="ltr"><div class="gmail_quote"><div class="gmail_attr">Hi Hans,</div><div class="gmail_attr"><br></div><div class="gmail_attr">I accidentally pushed a branch to the upstream repo instead of a fork. I've deleted it shortly after. It has no relation to the release branch.<br></div><div class="gmail_attr"><br></div><div class="gmail_attr">Regards,<br></div><div class="gmail_attr">Nikita<br></div><div dir="ltr" class="gmail_attr"><br></div><div dir="ltr" class="gmail_attr">On Mon, Jul 20, 2020 at 11:24 AM Hans Wennborg <<a href="mailto:hans@chromium.org">hans@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Nikita,<br>
<br>
Where did this come from? The commit message doesn't mention a code<br>
review or if this is a cherry-pick from something on trunk.<br>
<br>
Please always check with me before pushing anything to the release branch.<br>
<br>
Thanks,<br>
Hans<br>
<br>
On Sun, Jul 19, 2020 at 7:27 PM Nikita Popov via llvm-branch-commits<br>
<<a href="mailto:llvm-branch-commits@lists.llvm.org" target="_blank">llvm-branch-commits@lists.llvm.org</a>> wrote:<br>
><br>
><br>
> Author: Nikita Popov<br>
> Date: 2020-07-19T19:26:45+02:00<br>
> New Revision: 081c25553185740fde7d93d2a32ef4e87ae480aa<br>
><br>
> URL: <a href="https://github.com/llvm/llvm-project/commit/081c25553185740fde7d93d2a32ef4e87ae480aa" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/081c25553185740fde7d93d2a32ef4e87ae480aa</a><br>
> DIFF: <a href="https://github.com/llvm/llvm-project/commit/081c25553185740fde7d93d2a32ef4e87ae480aa.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/081c25553185740fde7d93d2a32ef4e87ae480aa.diff</a><br>
><br>
> LOG: [ValueTracking] Let isGuaranteedNotToBeUndefOrPoison use canCreateUndefOrPoison<br>
><br>
> Added:<br>
><br>
><br>
> Modified:<br>
>     llvm/include/llvm/Analysis/ValueTracking.h<br>
>     llvm/lib/Analysis/ValueTracking.cpp<br>
>     llvm/test/Transforms/DivRemPairs/PowerPC/div-expanded-rem-pair.ll<br>
>     llvm/test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll<br>
>     llvm/test/Transforms/InstSimplify/freeze-noundef.ll<br>
>     llvm/test/Transforms/InstSimplify/freeze.ll<br>
><br>
> Removed:<br>
><br>
><br>
><br>
> ################################################################################<br>
> diff  --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h<br>
> index 178f61563cd7..ce5aea2e8d34 100644<br>
> --- a/llvm/include/llvm/Analysis/ValueTracking.h<br>
> +++ b/llvm/include/llvm/Analysis/ValueTracking.h<br>
> @@ -607,7 +607,8 @@ class Value;<br>
>    bool canCreatePoison(const Operator *Op);<br>
><br>
>    /// Return true if this function can prove that V is never undef value<br>
> -  /// or poison value.<br>
> +  /// or poison value. If V is an aggregate value or vector, check whether all<br>
> +  /// elements (except padding) are not undef or poison.<br>
>    /// Note that this is<br>
> diff erent from canCreateUndefOrPoison because the<br>
>    /// function assumes Op's operands are not poison/undef.<br>
>    ///<br>
><br>
> diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp<br>
> index 380022c10ace..ed22718d866e 100644<br>
> --- a/llvm/lib/Analysis/ValueTracking.cpp<br>
> +++ b/llvm/lib/Analysis/ValueTracking.cpp<br>
> @@ -4779,23 +4779,13 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,<br>
>    if (Depth >= MaxDepth)<br>
>      return false;<br>
><br>
> -  // If the value is a freeze instruction, then it can never<br>
> -  // be undef or poison.<br>
> -  if (isa<FreezeInst>(V))<br>
> -    return true;<br>
> -  // TODO: Some instructions are guaranteed to return neither undef<br>
> -  // nor poison if their arguments are not poison/undef.<br>
> -<br>
> -  if (auto *A = dyn_cast<Argument>(V)) {<br>
> -    // NoUndef does not guarantee that paddings are not undef.<br>
> +  if (const auto *A = dyn_cast<Argument>(V)) {<br>
>      if (A->hasAttribute(Attribute::NoUndef))<br>
>        return true;<br>
>    }<br>
><br>
>    if (auto *C = dyn_cast<Constant>(V)) {<br>
> -    // TODO: We can analyze ConstExpr by opcode to determine if there is any<br>
> -    //       possibility of poison.<br>
> -    if (isa<UndefValue>(C) || isa<ConstantExpr>(C))<br>
> +    if (isa<UndefValue>(C))<br>
>        return false;<br>
><br>
>      if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(V) ||<br>
> @@ -4804,9 +4794,6 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,<br>
><br>
>      if (C->getType()->isVectorTy())<br>
>        return !C->containsUndefElement() && !C->containsConstantExpression();<br>
> -<br>
> -    // TODO: Recursively analyze aggregates or other constants.<br>
> -    return false;<br>
>    }<br>
><br>
>    // Strip cast operations from a pointer value.<br>
> @@ -4826,31 +4813,25 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,<br>
>      return isGuaranteedNotToBeUndefOrPoison(V, CtxI, DT, Depth + 1);<br>
>    };<br>
><br>
> -  if (auto *I = dyn_cast<Instruction>(V)) {<br>
> -    switch (I->getOpcode()) {<br>
> -    case Instruction::GetElementPtr: {<br>
> -      auto *GEPI = dyn_cast<GetElementPtrInst>(I);<br>
> -      if (!GEPI->isInBounds() && llvm::all_of(GEPI->operands(), OpCheck))<br>
> -        return true;<br>
> -      break;<br>
> -    }<br>
> -    case Instruction::FCmp: {<br>
> -      auto *FI = dyn_cast<FCmpInst>(I);<br>
> -      if (FI->getFastMathFlags().none() &&<br>
> -          llvm::all_of(FI->operands(), OpCheck))<br>
> -        return true;<br>
> -      break;<br>
> -    }<br>
> -    case Instruction::BitCast:<br>
> -    case Instruction::PHI:<br>
> -    case Instruction::ICmp:<br>
> -      if (llvm::all_of(I->operands(), OpCheck))<br>
> +  if (auto *Opr = dyn_cast<Operator>(V)) {<br>
> +    // If the value is a freeze instruction, then it can never<br>
> +    // be undef or poison.<br>
> +    if (isa<FreezeInst>(V))<br>
> +      return true;<br>
> +<br>
> +    if (const auto *CB = dyn_cast<CallBase>(V)) {<br>
> +      if (CB->hasRetAttr(Attribute::NoUndef))<br>
>          return true;<br>
> -      break;<br>
> -    default:<br>
> -      break;<br>
>      }<br>
><br>
> +    if (canCreateUndefOrPoison(Opr))<br>
> +      return false;<br>
> +<br>
> +    if (all_of(Opr->operands(), OpCheck))<br>
> +      return true;<br>
> +  }<br>
> +<br>
> +  if (auto *I = dyn_cast<Instruction>(V)) {<br>
>      if (programUndefinedIfPoison(I) && I->getType()->isIntegerTy(1))<br>
>        // Note: once we have an agreement that poison is a value-wise concept,<br>
>        // we can remove the isIntegerTy(1) constraint.<br>
><br>
> diff  --git a/llvm/test/Transforms/DivRemPairs/PowerPC/div-expanded-rem-pair.ll b/llvm/test/Transforms/DivRemPairs/PowerPC/div-expanded-rem-pair.ll<br>
> index 4b640b98e302..277d3de7c712 100644<br>
> --- a/llvm/test/Transforms/DivRemPairs/PowerPC/div-expanded-rem-pair.ll<br>
> +++ b/llvm/test/Transforms/DivRemPairs/PowerPC/div-expanded-rem-pair.ll<br>
> @@ -106,12 +106,11 @@ define i32 @srem_of_srem_unexpanded(i32 %X, i32 %Y, i32 %Z) {<br>
>  ; CHECK-NEXT:    [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]<br>
>  ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[T1]], [[T0_FROZEN]]<br>
>  ; CHECK-NEXT:    [[T3_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]]<br>
> -; CHECK-NEXT:    [[T3_DECOMPOSED_FROZEN:%.*]] = freeze i32 [[T3_DECOMPOSED]]<br>
>  ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i32 [[Y]]<br>
> -; CHECK-NEXT:    [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED_FROZEN]], [[Y_FROZEN]]<br>
> +; CHECK-NEXT:    [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED]], [[Y_FROZEN]]<br>
>  ; CHECK-NEXT:    [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]<br>
>  ; CHECK-NEXT:    [[TMP2:%.*]] = mul i32 [[T4]], [[Y_FROZEN]]<br>
> -; CHECK-NEXT:    [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED_FROZEN]], [[TMP2]]<br>
> +; CHECK-NEXT:    [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED]], [[TMP2]]<br>
>  ; CHECK-NEXT:    ret i32 [[T6_DECOMPOSED]]<br>
>  ;<br>
>    %t0 = mul nsw i32 %Z, %Y<br>
><br>
> diff  --git a/llvm/test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll b/llvm/test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll<br>
> index 3692d7d224f1..9e6d85d9920a 100644<br>
> --- a/llvm/test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll<br>
> +++ b/llvm/test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll<br>
> @@ -175,12 +175,11 @@ define i32 @srem_of_srem_unexpanded(i32 %X, i32 %Y, i32 %Z) {<br>
>  ; CHECK-NEXT:    [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]<br>
>  ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[T1]], [[T0_FROZEN]]<br>
>  ; CHECK-NEXT:    [[T3_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]]<br>
> -; CHECK-NEXT:    [[T3_DECOMPOSED_FROZEN:%.*]] = freeze i32 [[T3_DECOMPOSED]]<br>
>  ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i32 [[Y]]<br>
> -; CHECK-NEXT:    [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED_FROZEN]], [[Y_FROZEN]]<br>
> +; CHECK-NEXT:    [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED]], [[Y_FROZEN]]<br>
>  ; CHECK-NEXT:    [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]<br>
>  ; CHECK-NEXT:    [[TMP2:%.*]] = mul i32 [[T4]], [[Y_FROZEN]]<br>
> -; CHECK-NEXT:    [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED_FROZEN]], [[TMP2]]<br>
> +; CHECK-NEXT:    [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED]], [[TMP2]]<br>
>  ; CHECK-NEXT:    ret i32 [[T6_DECOMPOSED]]<br>
>  ;<br>
>    %t0 = mul nsw i32 %Z, %Y<br>
><br>
> diff  --git a/llvm/test/Transforms/InstSimplify/freeze-noundef.ll b/llvm/test/Transforms/InstSimplify/freeze-noundef.ll<br>
> index 424477891058..f2e897b507e3 100644<br>
> --- a/llvm/test/Transforms/InstSimplify/freeze-noundef.ll<br>
> +++ b/llvm/test/Transforms/InstSimplify/freeze-noundef.ll<br>
> @@ -19,12 +19,10 @@ define i1 @icmp(i8 noundef %x, i8 noundef %y) {<br>
>    ret i1 %f<br>
>  }<br>
><br>
> -; TODO: should look into binary operations<br>
>  define i1 @or(i1 noundef %x, i1 noundef %x2) {<br>
>  ; CHECK-LABEL: @or(<br>
>  ; CHECK-NEXT:    [[Y:%.*]] = or i1 [[X:%.*]], [[X2:%.*]]<br>
> -; CHECK-NEXT:    [[Z:%.*]] = freeze i1 [[Y]]<br>
> -; CHECK-NEXT:    ret i1 [[Z]]<br>
> +; CHECK-NEXT:    ret i1 [[Y]]<br>
>  ;<br>
>    %y = or i1 %x, %x2<br>
>    %z = freeze i1 %y<br>
> @@ -42,12 +40,10 @@ define i1 @or2(i1 noundef %x, i1 %x2) {<br>
>    ret i1 %z<br>
>  }<br>
><br>
> -; TODO: should look into binary operations<br>
>  define i8 @add(i8 noundef %x) {<br>
>  ; CHECK-LABEL: @add(<br>
>  ; CHECK-NEXT:    [[Y:%.*]] = add i8 [[X:%.*]], 1<br>
> -; CHECK-NEXT:    [[Z:%.*]] = freeze i8 [[Y]]<br>
> -; CHECK-NEXT:    ret i8 [[Z]]<br>
> +; CHECK-NEXT:    ret i8 [[Y]]<br>
>  ;<br>
>    %y = add i8 %x, 1<br>
>    %z = freeze i8 %y<br>
> @@ -77,21 +73,18 @@ define {i8, i32} @aggr({i8, i32} noundef %x) {<br>
>  define i32 @extract({i8, i32} noundef %x) {<br>
>  ; CHECK-LABEL: @extract(<br>
>  ; CHECK-NEXT:    [[Y:%.*]] = extractvalue { i8, i32 } [[X:%.*]], 1<br>
> -; CHECK-NEXT:    [[Z:%.*]] = freeze i32 [[Y]]<br>
> -; CHECK-NEXT:    ret i32 [[Z]]<br>
> +; CHECK-NEXT:    ret i32 [[Y]]<br>
>  ;<br>
>    %y = extractvalue {i8, i32} %x, 1<br>
>    %z = freeze i32 %y<br>
>    ret i32 %z<br>
>  }<br>
><br>
> -; TODO: should look into extract operations<br>
>  define i32 @extract2({i8, {i8, i32}} noundef %x) {<br>
>  ; CHECK-LABEL: @extract2(<br>
>  ; CHECK-NEXT:    [[Y:%.*]] = extractvalue { i8, { i8, i32 } } [[X:%.*]], 1<br>
>  ; CHECK-NEXT:    [[Z:%.*]] = extractvalue { i8, i32 } [[Y]], 1<br>
> -; CHECK-NEXT:    [[W:%.*]] = freeze i32 [[Z]]<br>
> -; CHECK-NEXT:    ret i32 [[W]]<br>
> +; CHECK-NEXT:    ret i32 [[Z]]<br>
>  ;<br>
>    %y = extractvalue {i8, {i8, i32}} %x, 1<br>
>    %z = extractvalue {i8, i32} %y, 1<br>
><br>
> diff  --git a/llvm/test/Transforms/InstSimplify/freeze.ll b/llvm/test/Transforms/InstSimplify/freeze.ll<br>
> index 306f293f7be7..8659687f07e7 100644<br>
> --- a/llvm/test/Transforms/InstSimplify/freeze.ll<br>
> +++ b/llvm/test/Transforms/InstSimplify/freeze.ll<br>
> @@ -116,13 +116,28 @@ define <2 x float> @constvector_FP_noopt() {<br>
><br>
>  define float @constant_expr() {<br>
>  ; CHECK-LABEL: @constant_expr(<br>
> -; CHECK-NEXT:    [[R:%.*]] = freeze float bitcast (i32 ptrtoint (i16* @g to i32) to float)<br>
> -; CHECK-NEXT:    ret float [[R]]<br>
> +; CHECK-NEXT:    ret float bitcast (i32 ptrtoint (i16* @g to i32) to float)<br>
>  ;<br>
>    %r = freeze float bitcast (i32 ptrtoint (i16* @g to i32) to float)<br>
>    ret float %r<br>
>  }<br>
><br>
> +define i8* @constant_expr2() {<br>
> +; CHECK-LABEL: @constant_expr2(<br>
> +; CHECK-NEXT:    ret i8* bitcast (i16* @g to i8*)<br>
> +;<br>
> +  %r = freeze i8* bitcast (i16* @g to i8*)<br>
> +  ret i8* %r<br>
> +}<br>
> +<br>
> +define i32* @constant_expr3() {<br>
> +; CHECK-LABEL: @constant_expr3(<br>
> +; CHECK-NEXT:    ret i32* getelementptr (i32, i32* @glb, i64 3)<br>
> +;<br>
> +  %r = freeze i32* getelementptr (i32, i32* @glb, i64 3)<br>
> +  ret i32* %r<br>
> +}<br>
> +<br>
>  ; Negative test<br>
><br>
>  define <2 x i31> @vector_element_constant_expr() {<br>
> @@ -136,7 +151,7 @@ define <2 x i31> @vector_element_constant_expr() {<br>
><br>
>  define void @alloca() {<br>
>  ; CHECK-LABEL: @alloca(<br>
> -; CHECK-NEXT:    [[P:%.*]] = alloca i8<br>
> +; CHECK-NEXT:    [[P:%.*]] = alloca i8, align 1<br>
>  ; CHECK-NEXT:    call void @f3(i8* [[P]])<br>
>  ; CHECK-NEXT:    ret void<br>
>  ;<br>
> @@ -148,7 +163,7 @@ define void @alloca() {<br>
><br>
>  define i8* @gep() {<br>
>  ; CHECK-LABEL: @gep(<br>
> -; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8]<br>
> +; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8], align 1<br>
>  ; CHECK-NEXT:    [[Q:%.*]] = getelementptr [4 x i8], [4 x i8]* [[P]], i32 0, i32 6<br>
>  ; CHECK-NEXT:    ret i8* [[Q]]<br>
>  ;<br>
> @@ -171,7 +186,7 @@ define i8* @gep_noopt(i32 %arg) {<br>
><br>
>  define i8* @gep_inbounds() {<br>
>  ; CHECK-LABEL: @gep_inbounds(<br>
> -; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8]<br>
> +; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8], align 1<br>
>  ; CHECK-NEXT:    [[Q:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[P]], i32 0, i32 0<br>
>  ; CHECK-NEXT:    ret i8* [[Q]]<br>
>  ;<br>
> @@ -183,7 +198,7 @@ define i8* @gep_inbounds() {<br>
><br>
>  define i8* @gep_inbounds_noopt(i32 %arg) {<br>
>  ; CHECK-LABEL: @gep_inbounds_noopt(<br>
> -; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8]<br>
> +; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8], align 1<br>
>  ; CHECK-NEXT:    [[Q:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[P]], i32 0, i32 [[ARG:%.*]]<br>
>  ; CHECK-NEXT:    [[Q2:%.*]] = freeze i8* [[Q]]<br>
>  ; CHECK-NEXT:    ret i8* [[Q2]]<br>
><br>
><br>
><br>
> _______________________________________________<br>
> llvm-branch-commits mailing list<br>
> <a href="mailto:llvm-branch-commits@lists.llvm.org" target="_blank">llvm-branch-commits@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits</a><br>
</blockquote></div></div>