[llvm] 810b5c4 - [NewGVN] add context instruction for SimplifyQuery

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 21 21:25:29 PDT 2022


Author: chenglin.bi
Date: 2022-06-22T12:25:24+08:00
New Revision: 810b5c471fe3b7f8b1e0038d2a9c5a2f47d49717

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

LOG: [NewGVN] add context instruction for SimplifyQuery

NewGVN will find operator from other context. ValueTracking currently doesn't have a way to run completely without context instruction.
So it will use operator itself as conext instruction.
If the operator in another branch will never be executed but it has an assume, it may caused value tracking use the assume to do wrong simpilfy.

It would be better to make these simplification queries not use context at all, but that would require some API changes.
For now we just use the orignial instruction as context instruction to fix the issue.

Fix #56039

Reviewed By: nikic

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

Added: 
    llvm/test/Transforms/NewGVN/sq-ctxi.ll

Modified: 
    llvm/lib/Transforms/Scalar/NewGVN.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 6d1f09f5166d5..302eec1bced89 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -1074,6 +1074,9 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
                                                  Value *Arg1, Value *Arg2,
                                                  Instruction *I) const {
   auto *E = new (ExpressionAllocator) BasicExpression(2);
+  // TODO: we need to remove context instruction after Value Tracking
+  // can run without context instruction
+  const SimplifyQuery Q = SQ.getWithInstruction(I);
 
   E->setType(T);
   E->setOpcode(Opcode);
@@ -1089,7 +1092,7 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
   E->op_push_back(lookupOperandLeader(Arg1));
   E->op_push_back(lookupOperandLeader(Arg2));
 
-  Value *V = simplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), SQ);
+  Value *V = simplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), Q);
   if (auto Simplified = checkExprResults(E, I, V)) {
     addAdditionalUsers(Simplified, I);
     return Simplified.Expr;
@@ -1145,6 +1148,9 @@ NewGVN::ExprResult NewGVN::checkExprResults(Expression *E, Instruction *I,
 
 NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
   auto *E = new (ExpressionAllocator) BasicExpression(I->getNumOperands());
+  // TODO: we need to remove context instruction after Value Tracking
+  // can run without context instruction
+  const SimplifyQuery Q = SQ.getWithInstruction(I);
 
   bool AllConstant = setBasicExpressionInfo(I, E);
 
@@ -1173,7 +1179,7 @@ NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
     assert((E->getOperand(0)->getType() == I->getOperand(0)->getType() &&
             E->getOperand(1)->getType() == I->getOperand(1)->getType()));
     Value *V =
-        simplifyCmpInst(Predicate, E->getOperand(0), E->getOperand(1), SQ);
+        simplifyCmpInst(Predicate, E->getOperand(0), E->getOperand(1), Q);
     if (auto Simplified = checkExprResults(E, I, V))
       return Simplified;
   } else if (isa<SelectInst>(I)) {
@@ -1182,25 +1188,25 @@ NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
       assert(E->getOperand(1)->getType() == I->getOperand(1)->getType() &&
              E->getOperand(2)->getType() == I->getOperand(2)->getType());
       Value *V = simplifySelectInst(E->getOperand(0), E->getOperand(1),
-                                    E->getOperand(2), SQ);
+                                    E->getOperand(2), Q);
       if (auto Simplified = checkExprResults(E, I, V))
         return Simplified;
     }
   } else if (I->isBinaryOp()) {
     Value *V =
-        simplifyBinOp(E->getOpcode(), E->getOperand(0), E->getOperand(1), SQ);
+        simplifyBinOp(E->getOpcode(), E->getOperand(0), E->getOperand(1), Q);
     if (auto Simplified = checkExprResults(E, I, V))
       return Simplified;
   } else if (auto *CI = dyn_cast<CastInst>(I)) {
     Value *V =
-        simplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), SQ);
+        simplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), Q);
     if (auto Simplified = checkExprResults(E, I, V))
       return Simplified;
   } else if (auto *GEPI = dyn_cast<GetElementPtrInst>(I)) {
     Value *V =
         simplifyGEPInst(GEPI->getSourceElementType(), *E->op_begin(),
                         makeArrayRef(std::next(E->op_begin()), E->op_end()),
-                        GEPI->isInBounds(), SQ);
+                        GEPI->isInBounds(), Q);
     if (auto Simplified = checkExprResults(E, I, V))
       return Simplified;
   } else if (AllConstant) {

diff  --git a/llvm/test/Transforms/NewGVN/sq-ctxi.ll b/llvm/test/Transforms/NewGVN/sq-ctxi.ll
new file mode 100644
index 0000000000000..ef7380437176c
--- /dev/null
+++ b/llvm/test/Transforms/NewGVN/sq-ctxi.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=newgvn -S | FileCheck %s
+
+; github issue #56039
+define i8 @src(i8* %a, i8* %b, i1 %c) {
+; CHECK-LABEL: @src(
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[LB1:%.*]] = load i8, i8* [[B:%.*]], align 1
+; CHECK-NEXT:    [[TOBOOL3_NOT_I:%.*]] = icmp eq i8 [[LB1]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL3_NOT_I]], label [[BB4:%.*]], label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[LB2:%.*]] = load i8, i8* [[B]], align 1
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i8 0, [[LB2]]
+; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP_NOT_I]])
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    [[LA:%.*]] = load i8, i8* [[A:%.*]], align 1
+; CHECK-NEXT:    br label [[BB4]]
+; CHECK:       bb4:
+; CHECK-NEXT:    ret i8 0
+;
+  br i1 %c, label %bb1, label %bb2
+
+bb1:
+  %lb1 = load i8, i8* %b
+  %tobool3.not.i = icmp eq i8 %lb1, 0
+  br i1 %tobool3.not.i, label %bb4, label %bb3
+
+bb2:
+  %lb2 = load i8, i8* %b
+  %cmp.not.i = icmp ult i8 0, %lb2
+  tail call void @llvm.assume(i1 %cmp.not.i)
+  br label %bb3
+
+bb3:
+  %p = phi i8 [ %lb1, %bb1 ], [ %lb2, %bb2 ]
+  %la = load i8, i8* %a
+  %xor = xor i8 %la, %p
+  br label %bb4
+
+bb4:
+  ret i8 0
+}
+
+declare void @llvm.assume(i1)


        


More information about the llvm-commits mailing list