[llvm] ac74e7a - [InstSimplify] Only check self-simplify in simplifyInstruction()

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 17 06:52:50 PDT 2022


Author: Nikita Popov
Date: 2022-10-17T15:52:38+02:00
New Revision: ac74e7a7806480a000c9a3502405c3dedd8810de

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

LOG: [InstSimplify] Only check self-simplify in simplifyInstruction()

InstSimplify currently checks whether the instruction simplifies
back to itself, and returns undef in that case. Generally, this
should only occur in unreachable code.

However, this was also done for the simplifyInstructionWithOperands()
API. In that case, the instruction only serves as a template that
provides the opcode and other non-operand data. In this case,
simplifying back to the same "instruction" may be expected. This
caused PR58401 in conjunction with D134954.

As such, move this check into simplifyInstruction() only. The only
other caller of simplifyInstructionWithOperands() also handles the
self-simplification case explicitly.

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 7b2298443049..fe7b63c36128 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6375,7 +6375,6 @@ static Value *simplifyInstructionWithOperands(Instruction *I,
                                               const SimplifyQuery &SQ,
                                               OptimizationRemarkEmitter *ORE) {
   const SimplifyQuery Q = SQ.CxtI ? SQ : SQ.getWithInstruction(I);
-  Value *Result = nullptr;
 
   switch (I->getOpcode()) {
   default:
@@ -6383,145 +6382,104 @@ static Value *simplifyInstructionWithOperands(Instruction *I,
       SmallVector<Constant *, 8> NewConstOps(NewOps.size());
       transform(NewOps, NewConstOps.begin(),
                 [](Value *V) { return cast<Constant>(V); });
-      Result = ConstantFoldInstOperands(I, NewConstOps, Q.DL, Q.TLI);
+      return ConstantFoldInstOperands(I, NewConstOps, Q.DL, Q.TLI);
     }
-    break;
+    return nullptr;
   case Instruction::FNeg:
-    Result = simplifyFNegInst(NewOps[0], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFNegInst(NewOps[0], I->getFastMathFlags(), Q);
   case Instruction::FAdd:
-    Result = simplifyFAddInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFAddInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
   case Instruction::Add:
-    Result = simplifyAddInst(
-        NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
-        Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q);
-    break;
+    return simplifyAddInst(NewOps[0], NewOps[1],
+                           Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
+                           Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q);
   case Instruction::FSub:
-    Result = simplifyFSubInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFSubInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
   case Instruction::Sub:
-    Result = simplifySubInst(
-        NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
-        Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q);
-    break;
+    return simplifySubInst(NewOps[0], NewOps[1],
+                           Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
+                           Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q);
   case Instruction::FMul:
-    Result = simplifyFMulInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFMulInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
   case Instruction::Mul:
-    Result = simplifyMulInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyMulInst(NewOps[0], NewOps[1], Q);
   case Instruction::SDiv:
-    Result = simplifySDivInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifySDivInst(NewOps[0], NewOps[1], Q);
   case Instruction::UDiv:
-    Result = simplifyUDivInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyUDivInst(NewOps[0], NewOps[1], Q);
   case Instruction::FDiv:
-    Result = simplifyFDivInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFDivInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
   case Instruction::SRem:
-    Result = simplifySRemInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifySRemInst(NewOps[0], NewOps[1], Q);
   case Instruction::URem:
-    Result = simplifyURemInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyURemInst(NewOps[0], NewOps[1], Q);
   case Instruction::FRem:
-    Result = simplifyFRemInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFRemInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q);
   case Instruction::Shl:
-    Result = simplifyShlInst(
-        NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
-        Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q);
-    break;
+    return simplifyShlInst(NewOps[0], NewOps[1],
+                           Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
+                           Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q);
   case Instruction::LShr:
-    Result = simplifyLShrInst(NewOps[0], NewOps[1],
-                              Q.IIQ.isExact(cast<BinaryOperator>(I)), Q);
-    break;
+    return simplifyLShrInst(NewOps[0], NewOps[1],
+                            Q.IIQ.isExact(cast<BinaryOperator>(I)), Q);
   case Instruction::AShr:
-    Result = simplifyAShrInst(NewOps[0], NewOps[1],
-                              Q.IIQ.isExact(cast<BinaryOperator>(I)), Q);
-    break;
+    return simplifyAShrInst(NewOps[0], NewOps[1],
+                            Q.IIQ.isExact(cast<BinaryOperator>(I)), Q);
   case Instruction::And:
-    Result = simplifyAndInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyAndInst(NewOps[0], NewOps[1], Q);
   case Instruction::Or:
-    Result = simplifyOrInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyOrInst(NewOps[0], NewOps[1], Q);
   case Instruction::Xor:
-    Result = simplifyXorInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyXorInst(NewOps[0], NewOps[1], Q);
   case Instruction::ICmp:
-    Result = simplifyICmpInst(cast<ICmpInst>(I)->getPredicate(), NewOps[0],
-                              NewOps[1], Q);
-    break;
+    return simplifyICmpInst(cast<ICmpInst>(I)->getPredicate(), NewOps[0],
+                            NewOps[1], Q);
   case Instruction::FCmp:
-    Result = simplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), NewOps[0],
-                              NewOps[1], I->getFastMathFlags(), Q);
-    break;
+    return simplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), NewOps[0],
+                            NewOps[1], I->getFastMathFlags(), Q);
   case Instruction::Select:
-    Result = simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q);
+    return simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q);
     break;
   case Instruction::GetElementPtr: {
     auto *GEPI = cast<GetElementPtrInst>(I);
-    Result =
-        simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0],
-                        makeArrayRef(NewOps).slice(1), GEPI->isInBounds(), Q);
-    break;
+    return simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0],
+                           makeArrayRef(NewOps).slice(1), GEPI->isInBounds(),
+                           Q);
   }
   case Instruction::InsertValue: {
     InsertValueInst *IV = cast<InsertValueInst>(I);
-    Result = simplifyInsertValueInst(NewOps[0], NewOps[1], IV->getIndices(), Q);
-    break;
-  }
-  case Instruction::InsertElement: {
-    Result = simplifyInsertElementInst(NewOps[0], NewOps[1], NewOps[2], Q);
-    break;
+    return simplifyInsertValueInst(NewOps[0], NewOps[1], IV->getIndices(), Q);
   }
+  case Instruction::InsertElement:
+    return simplifyInsertElementInst(NewOps[0], NewOps[1], NewOps[2], Q);
   case Instruction::ExtractValue: {
     auto *EVI = cast<ExtractValueInst>(I);
-    Result = simplifyExtractValueInst(NewOps[0], EVI->getIndices(), Q);
-    break;
-  }
-  case Instruction::ExtractElement: {
-    Result = simplifyExtractElementInst(NewOps[0], NewOps[1], Q);
-    break;
+    return simplifyExtractValueInst(NewOps[0], EVI->getIndices(), Q);
   }
+  case Instruction::ExtractElement:
+    return simplifyExtractElementInst(NewOps[0], NewOps[1], Q);
   case Instruction::ShuffleVector: {
     auto *SVI = cast<ShuffleVectorInst>(I);
-    Result = simplifyShuffleVectorInst(
-        NewOps[0], NewOps[1], SVI->getShuffleMask(), SVI->getType(), Q);
-    break;
+    return simplifyShuffleVectorInst(NewOps[0], NewOps[1],
+                                     SVI->getShuffleMask(), SVI->getType(), Q);
   }
   case Instruction::PHI:
-    Result = simplifyPHINode(cast<PHINode>(I), NewOps, Q);
-    break;
-  case Instruction::Call: {
+    return simplifyPHINode(cast<PHINode>(I), NewOps, Q);
+  case Instruction::Call:
     // TODO: Use NewOps
-    Result = simplifyCall(cast<CallInst>(I), Q);
-    break;
-  }
+    return simplifyCall(cast<CallInst>(I), Q);
   case Instruction::Freeze:
-    Result = llvm::simplifyFreezeInst(NewOps[0], Q);
-    break;
+    return llvm::simplifyFreezeInst(NewOps[0], Q);
 #define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
 #include "llvm/IR/Instruction.def"
 #undef HANDLE_CAST_INST
-    Result = simplifyCastInst(I->getOpcode(), NewOps[0], I->getType(), Q);
-    break;
+    return simplifyCastInst(I->getOpcode(), NewOps[0], I->getType(), Q);
   case Instruction::Alloca:
     // No simplifications for Alloca and it can't be constant folded.
-    Result = nullptr;
-    break;
+    return nullptr;
   case Instruction::Load:
-    Result = simplifyLoadInst(cast<LoadInst>(I), NewOps[0], Q);
-    break;
+    return simplifyLoadInst(cast<LoadInst>(I), NewOps[0], Q);
   }
-
-  /// If called on unreachable code, the above logic may report that the
-  /// instruction simplified to itself.  Make life easier for users by
-  /// detecting that case here, returning a safe value instead.
-  return Result == I ? UndefValue::get(I->getType()) : Result;
 }
 
 Value *llvm::simplifyInstructionWithOperands(Instruction *I,
@@ -6536,7 +6494,12 @@ Value *llvm::simplifyInstructionWithOperands(Instruction *I,
 Value *llvm::simplifyInstruction(Instruction *I, const SimplifyQuery &SQ,
                                  OptimizationRemarkEmitter *ORE) {
   SmallVector<Value *, 8> Ops(I->operands());
-  return ::simplifyInstructionWithOperands(I, Ops, SQ, ORE);
+  Value *Result = ::simplifyInstructionWithOperands(I, Ops, SQ, ORE);
+
+  /// If called on unreachable code, the instruction may simplify to itself.
+  /// Make life easier for users by detecting that case here, and returning a
+  /// safe value instead.
+  return Result == I ? UndefValue::get(I->getType()) : Result;
 }
 
 /// Implementation of recursive simplification through an instruction's


        


More information about the llvm-commits mailing list