[llvm] 9ca2c30 - [InstSimplify] Fix poison safety in insertvalue fold

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 16 00:39:52 PST 2023


Author: Nikita Popov
Date: 2023-02-16T09:39:44+01:00
New Revision: 9ca2c309ab0678fae48f96131b92754d0978c130

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

LOG: [InstSimplify] Fix poison safety in insertvalue fold

We can only fold insertvalue undef, (extractvalue x, n) to x
if x is not poison, otherwise we might be replacing undef with
poison (https://alive2.llvm.org/ce/z/fnw3c8). The insertvalue
poison case is always fine.

I didn't go to particularly large effort to preserve cases where
folding with undef is still legal (mainly when there is a chain of
multiple inserts that end up covering the whole aggregate),
because this shouldn't really occur in practice: We should always
be generating the insertvalue poison form when constructing
aggregates nowadays.

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

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/Inline/pr50270.ll
    llvm/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll
    llvm/test/Transforms/InstSimplify/insertvalue.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d6664723af01b..865cd47b1ab76 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4892,8 +4892,11 @@ static Value *simplifyInsertValueInst(Value *Agg, Value *Val,
   if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Val))
     if (EV->getAggregateOperand()->getType() == Agg->getType() &&
         EV->getIndices() == Idxs) {
-      // insertvalue undef, (extractvalue y, n), n -> y
-      if (Q.isUndefValue(Agg))
+      // insertvalue poison, (extractvalue y, n), n -> y
+      // insertvalue undef, (extractvalue y, n), n -> y if y cannot be poison
+      if (isa<PoisonValue>(Agg) ||
+          (Q.isUndefValue(Agg) &&
+           isGuaranteedNotToBePoison(EV->getAggregateOperand())))
         return EV->getAggregateOperand();
 
       // insertvalue y, (extractvalue y, n), n -> y

diff  --git a/llvm/test/Transforms/Inline/pr50270.ll b/llvm/test/Transforms/Inline/pr50270.ll
index 98324087b7b08..e1798f474b4ba 100644
--- a/llvm/test/Transforms/Inline/pr50270.ll
+++ b/llvm/test/Transforms/Inline/pr50270.ll
@@ -10,17 +10,17 @@ declare { ptr } @opaque_callee()
 
 define { ptr } @callee(ptr %x) {
 ; CHECK-LABEL: @callee(
-; CHECK-NEXT:    [[RES:%.*]] = insertvalue { ptr } undef, ptr [[X:%.*]], 0
+; CHECK-NEXT:    [[RES:%.*]] = insertvalue { ptr } poison, ptr [[X:%.*]], 0
 ; CHECK-NEXT:    ret { ptr } [[RES]]
 ;
-  %res = insertvalue { ptr } undef, ptr %x, 0
+  %res = insertvalue { ptr } poison, ptr %x, 0
   ret { ptr } %res
 }
 
 ; @opaque_callee() should not receive noalias metadata here.
 define void @caller() {
 ; CHECK-LABEL: @caller(
-; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
 ; CHECK-NEXT:    [[S:%.*]] = call { ptr } @opaque_callee()
 ; CHECK-NEXT:    [[X:%.*]] = extractvalue { ptr } [[S]], 0
 ; CHECK-NEXT:    ret void
@@ -36,16 +36,16 @@ define void @caller() {
 ; else branch, not as the load in the if branch.
 define { ptr } @self_caller(i1 %c, ptr %a) {
 ; CHECK-LABEL: @self_caller(
-; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata [[META0]])
 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
 ; CHECK:       if:
 ; CHECK-NEXT:    [[S:%.*]] = call { ptr } @opaque_callee(), !noalias !0
 ; CHECK-NEXT:    [[X:%.*]] = extractvalue { ptr } [[S]], 0
-; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = load volatile i64, ptr [[X]], align 4, !alias.scope !3
 ; CHECK-NEXT:    ret { ptr } [[S]]
 ; CHECK:       else:
-; CHECK-NEXT:    [[R2:%.*]] = insertvalue { ptr } undef, ptr [[A:%.*]], 0
+; CHECK-NEXT:    [[R2:%.*]] = insertvalue { ptr } poison, ptr [[A:%.*]], 0
 ; CHECK-NEXT:    [[TMP2:%.*]] = load volatile i64, ptr [[A]], align 4, !alias.scope !0
 ; CHECK-NEXT:    ret { ptr } [[R2]]
 ;
@@ -59,7 +59,7 @@ if:
   ret { ptr } %r
 
 else:
-  %r2 = insertvalue { ptr } undef, ptr %a, 0
+  %r2 = insertvalue { ptr } poison, ptr %a, 0
   load volatile i64, ptr %a, !alias.scope !0
   ret { ptr } %r2
 }

diff  --git a/llvm/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll b/llvm/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll
index d9a89bf74a347..a296aca65bbf6 100644
--- a/llvm/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll
+++ b/llvm/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll
@@ -23,7 +23,7 @@ lpad:
   %ex = landingpad { ptr, i32 } cleanup
   %exc_ptr = extractvalue { ptr, i32 } %ex, 0
   %filter = extractvalue { ptr, i32 } %ex, 1
-  %exc_ptr2 = insertvalue { ptr, i32 } undef, ptr %exc_ptr, 0
+  %exc_ptr2 = insertvalue { ptr, i32 } poison, ptr %exc_ptr, 0
   %filter2 = insertvalue { ptr, i32 } %exc_ptr2, i32 %filter, 1
   resume { ptr, i32 } %filter2
 }

diff  --git a/llvm/test/Transforms/InstSimplify/insertvalue.ll b/llvm/test/Transforms/InstSimplify/insertvalue.ll
index b2360739530ea..441ced274ddc8 100644
--- a/llvm/test/Transforms/InstSimplify/insertvalue.ll
+++ b/llvm/test/Transforms/InstSimplify/insertvalue.ll
@@ -37,7 +37,9 @@ define {i32, i32} @insert_into_poison({i32, i32} %x) {
 
 define {i32, i32} @insert_into_undef({i32, i32} %x) {
 ; CHECK-LABEL: @insert_into_undef(
-; CHECK-NEXT:    ret { i32, i32 } [[X:%.*]]
+; CHECK-NEXT:    [[ELEM:%.*]] = extractvalue { i32, i32 } [[X:%.*]], 0
+; CHECK-NEXT:    [[V:%.*]] = insertvalue { i32, i32 } undef, i32 [[ELEM]], 0
+; CHECK-NEXT:    ret { i32, i32 } [[V]]
 ;
   %elem = extractvalue {i32, i32} %x, 0
   %v = insertvalue {i32, i32} undef, i32 %elem, 0


        


More information about the llvm-commits mailing list