[PATCH] D96663: [InstCombine] Fold nonnull (select c,null,p) to nonnull p

Juneyoung Lee via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 14 05:17:51 PST 2021


aqjune created this revision.
aqjune added reviewers: nikic, xbolva00, RKSimon.
Herald added a subscriber: hiraditya.
aqjune requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This is a simple patch that folds nonnull uses of select c,null,p to p.

Resolves llvm.org/pr48975.

This patch can be extended to detecting more patterns that are listed in SimplifyCFG's passingValueIsAlwaysUndefined in the future.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96663

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/test/Transforms/InstCombine/nonnull-select.ll


Index: llvm/test/Transforms/InstCombine/nonnull-select.ll
===================================================================
--- llvm/test/Transforms/InstCombine/nonnull-select.ll
+++ llvm/test/Transforms/InstCombine/nonnull-select.ll
@@ -5,11 +5,8 @@
 
 define nonnull i32* @pr48975(i32** %.0) {
 ; CHECK-LABEL: @pr48975(
-; CHECK-NEXT:    [[DOT1:%.*]] = load i32*, i32** [[DOT0:%.*]], align 8
-; CHECK-NEXT:    [[DOT2:%.*]] = icmp eq i32* [[DOT1]], null
-; CHECK-NEXT:    [[DOT3:%.*]] = bitcast i32** [[DOT0]] to i32*
-; CHECK-NEXT:    [[DOT4:%.*]] = select i1 [[DOT2]], i32* null, i32* [[DOT3]]
-; CHECK-NEXT:    ret i32* [[DOT4]]
+; CHECK-NEXT:    [[DOT3:%.*]] = bitcast i32** [[DOT0:%.*]] to i32*
+; CHECK-NEXT:    ret i32* [[DOT3]]
 ;
   %.1 = load i32*, i32** %.0, align 8
   %.2 = icmp eq i32* %.1, null
@@ -20,8 +17,7 @@
 
 define nonnull i32* @nonnull_ret(i1 %cond, i32* %p) {
 ; CHECK-LABEL: @nonnull_ret(
-; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND:%.*]], i32* [[P:%.*]], i32* null
-; CHECK-NEXT:    ret i32* [[RES]]
+; CHECK-NEXT:    ret i32* [[P:%.*]]
 ;
   %res = select i1 %cond, i32* %p, i32* null
   ret i32* %res
@@ -29,8 +25,7 @@
 
 define void @nonnull_call(i1 %cond, i32* %p) {
 ; CHECK-LABEL: @nonnull_call(
-; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND:%.*]], i32* null, i32* [[P:%.*]]
-; CHECK-NEXT:    call void @f(i32* nonnull [[RES]])
+; CHECK-NEXT:    call void @f(i32* nonnull [[P:%.*]])
 ; CHECK-NEXT:    ret void
 ;
   %res = select i1 %cond, i32* null, i32* %p
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2830,6 +2830,21 @@
     return nullptr;
 
   Value *ResultOp = RI.getOperand(0);
+
+  auto Attrs = RI.getFunction()->getAttributes();
+  if (Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull)) {
+    //   ptr = select _, null, p
+    //   ret ptr
+    // =>
+    //   ret p
+    Value *TrueVal, *FalseVal;
+    if (match(ResultOp, m_Select(m_Value(), m_Value(TrueVal), m_Value(FalseVal)))) {
+      bool IsTrueNull = isa<ConstantPointerNull>(TrueVal);
+      if (IsTrueNull || isa<ConstantPointerNull>(FalseVal))
+        return replaceOperand(RI, 0, IsTrueNull ? FalseVal : TrueVal);
+    }
+  }
+
   Type *VTy = ResultOp->getType();
   if (!VTy->isIntegerTy() || isa<Constant>(ResultOp))
     return nullptr;
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2258,6 +2258,27 @@
             Call, Builder.CreateBitOrPointerCast(ReturnedArg, CallTy));
     }
 
+  // Simplify nonnull arguments if possible.
+  //   ptr = select _, null, p
+  //   f(nonnull ptr)
+  // =>
+  //   f(nonnull p)
+  for (unsigned ArgNo = 0, N = Call.getNumArgOperands(); ArgNo != N; ++ArgNo) {
+    if (!Call.paramHasAttr(ArgNo, Attribute::NonNull))
+      continue;
+
+    Value *V = Call.getArgOperand(ArgNo);
+    Value *TrueVal, *FalseVal;
+    if (!match(V, m_Select(m_Value(), m_Value(TrueVal), m_Value(FalseVal))))
+      continue;
+
+    bool IsTrueNull = isa<ConstantPointerNull>(TrueVal);
+    if (IsTrueNull || isa<ConstantPointerNull>(FalseVal)) {
+      replaceUse(Call.getArgOperandUse(ArgNo), IsTrueNull ? FalseVal : TrueVal);
+      Changed = true;
+    }
+  }
+
   if (isAllocLikeFn(&Call, &TLI))
     return visitAllocSite(Call);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D96663.323610.patch
Type: text/x-patch
Size: 3603 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210214/a38bade4/attachment.bin>


More information about the llvm-commits mailing list