[llvm-branch-commits] [llvm] 9db3e5d - [InstCombine] Fix infinite loop in min/max load/store bitcast combine (PR44835)

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Feb 10 02:26:17 PST 2020


Author: Nikita Popov
Date: 2020-02-10T11:23:13+01:00
New Revision: 9db3e5d5156bc2a3ba8ec0d70ab7069a82472fbb

URL: https://github.com/llvm/llvm-project/commit/9db3e5d5156bc2a3ba8ec0d70ab7069a82472fbb
DIFF: https://github.com/llvm/llvm-project/commit/9db3e5d5156bc2a3ba8ec0d70ab7069a82472fbb.diff

LOG: [InstCombine] Fix infinite loop in min/max load/store bitcast combine (PR44835)

Fixes https://bugs.llvm.org/show_bug.cgi?id=44835. Skip the transform
if it wouldn't actually do anything (apart from removing and reinserting
the same instructions).

Note that the test case doesn't loop on current master anymore, only
on the LLVM 10 release branch. The issue is already mitigated on master
due to worklist order fixes, but we should fix the root cause there as well.

As a side note, we should probably assert in combineLoadToNewType()
that it does not combine to the same type. Not doing this here, because
this assertion would also be triggered in another place right now.

Differential Revision: https://reviews.llvm.org/D74278

(cherry picked from commit 23db9724d0e5490fa5a2a726acf015f84e2c87cf)

Added: 
    llvm/test/Transforms/InstCombine/pr44835.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index c288a7d8d403..74654f7ef51d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -1336,6 +1336,11 @@ static bool removeBitcastsFromLoadStoreOnMinMax(InstCombiner &IC,
   if (!isMinMaxWithLoads(LoadAddr, CmpLoadTy))
     return false;
 
+  // Make sure the type would actually change.
+  // This condition can be hit with chains of bitcasts.
+  if (LI->getType() == CmpLoadTy)
+    return false;
+
   // Make sure we're not changing the size of the load/store.
   const auto &DL = IC.getDataLayout();
   if (DL.getTypeStoreSizeInBits(LI->getType()) !=

diff  --git a/llvm/test/Transforms/InstCombine/pr44835.ll b/llvm/test/Transforms/InstCombine/pr44835.ll
new file mode 100644
index 000000000000..46c9fca6bb7a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/pr44835.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; This test used to cause an infinite loop in the load/store min/max bitcast
+; transform.
+
+define void @test(i32* %p, i32* %p2) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[V2:%.*]] = load i32, i32* [[P2:%.*]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V2]], [[V]]
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[CMP]], i32 [[V2]], i32 [[V]]
+; CHECK-NEXT:    store i32 [[TMP1]], i32* [[P]], align 4
+; CHECK-NEXT:    ret void
+;
+  %v = load i32, i32* %p, align 4
+  %v2 = load i32, i32* %p2, align 4
+  %cmp = icmp ult i32 %v2, %v
+  %sel = select i1 %cmp, i32* %p2, i32* %p
+  %p8 = bitcast i32* %p to i8*
+  %sel8 = bitcast i32* %sel to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %p8, i8* align 4 %sel8, i64 4, i1 false)
+  ret void
+}
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
+
+attributes #0 = { argmemonly nounwind willreturn }


        


More information about the llvm-branch-commits mailing list