[PATCH] D114648: [InstCombine] Sink noaliasing calls that can have side-effects

Anna Thomas via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 26 09:52:38 PST 2021


anna created this revision.
anna added reviewers: reames, nikic, fhahn, apilipenko, mkazantsev.
Herald added subscribers: jeroen.dobbelaere, hiraditya.
anna requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Further improvement to D109917 <https://reviews.llvm.org/D109917> so that we can sink noalias calls that
have side-effects down to their use. See updated testcases around
allocations.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114648

Files:
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/test/Transforms/InstCombine/sink_instruction.ll


Index: llvm/test/Transforms/InstCombine/sink_instruction.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sink_instruction.ll
+++ llvm/test/Transforms/InstCombine/sink_instruction.ll
@@ -242,12 +242,12 @@
   ret void
 }
 
-; TODO: We can sink down the allocation to its only use.
+; We can sink down the allocation to its only use.
 define i8** @test_allocation_sink_bc(i1 %cond) {
 ; CHECK-LABEL: @test_allocation_sink_bc(
-; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
-; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK:         br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
 ; CHECK:       if:
+; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
 ; CHECK-NEXT:    [[X:%.*]] = bitcast i8* [[A]] to i8**
 ; CHECK-NEXT:    ret i8** [[X]]
 ; CHECK:       else:
@@ -269,12 +269,12 @@
   ret i8** %Y
 }
 
-; TODO: We can sink down the allocation to its only use.
+; We can sink down the allocation to its only use.
 define void @test_allocation_sink(i1 %cond) {
 ; CHECK-LABEL: @test_allocation_sink(
-; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
-; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK:         br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
 ; CHECK:       if:
+; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
 ; CHECK-NEXT:    call void @check(i8* [[A]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       else:
@@ -291,15 +291,15 @@
   ret void
 }
 
-; TODO: We can sink this malloc as well down to the use block.
+; We can sink this malloc as well down to the use block.
 define void @test_allocation_sink_noalias_load(i1 %cond, i32 %i, i32* readonly %P) {
 ; CHECK-LABEL: @test_allocation_sink_noalias_load(
-; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
-; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[I:%.*]] to i64
+; CHECK:         [[IDXPROM:%.*]] = sext i32 [[I:%.*]] to i64
 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[IDXPROM]]
 ; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
 ; CHECK:       if:
+; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
 ; CHECK-NEXT:    call void @check(i8* [[A]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       else:
@@ -323,14 +323,14 @@
   ret void
 }
 
-; TODO: We can sink both allocations to its only use without them being
+; We can sink both allocations to its only use without them being
 ; incorrectly reordered.
 define void @test_allocation_sink2(i1 %cond) {
 ; CHECK-LABEL: @test_allocation_sink2(
+; CHECK:         br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK:       if:
 ; CHECK-NEXT:    [[A:%.*]] = call dereferenceable_or_null(16000) i8* @malloc(i32 16000)
 ; CHECK-NEXT:    [[B:%.*]] = call dereferenceable_or_null(16) i8* @malloc(i32 16)
-; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
-; CHECK:       if:
 ; CHECK-NEXT:    call void @check2(i8* [[A]], i8* [[B]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       else:
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3712,8 +3712,9 @@
       return false;
   }
   // We can only sink load instructions if there is nothing between the load and
-  // the end of block that could change the value.
-  if (I->mayReadFromMemory()) {
+  // the end of block that could change the value. We do not need to do these
+  // checks if we have a call with noalias return attribute.
+  if (I->mayReadFromMemory() && !isNoAliasCall(I)) {
     // We don't want to do any sophisticated alias analysis, so we only check
     // the instructions after I in I's parent block if we try to sink to its
     // successor block.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114648.390090.patch
Type: text/x-patch
Size: 4186 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211126/87876d81/attachment.bin>


More information about the llvm-commits mailing list