[llvm] [SROA] Prevent poison propagation in insertInteger() (PR #109240)

Junda Liu via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 18 23:19:25 PDT 2024


https://github.com/LLJJDD created https://github.com/llvm/llvm-project/pull/109240

When inserting an new integer to a larger old integer, freeze the old one first
in case it contains poison, otherwise the insertion still results in poison.

>From 241dc39ed196d3175a46d241a00b3b23c1b37825 Mon Sep 17 00:00:00 2001
From: Junda Liu <Junda.Liu at amd.com>
Date: Thu, 19 Sep 2024 12:02:32 +0800
Subject: [PATCH 1/2] [SROA] Precommit test to demonstrate problem

---
 .../Transforms/SROA/poison-propagation.ll     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 llvm/test/Transforms/SROA/poison-propagation.ll

diff --git a/llvm/test/Transforms/SROA/poison-propagation.ll b/llvm/test/Transforms/SROA/poison-propagation.ll
new file mode 100644
index 00000000000000..94778235466746
--- /dev/null
+++ b/llvm/test/Transforms/SROA/poison-propagation.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=sroa %s | FileCheck %s
+
+; Negative test: https://alive2.llvm.org/ce/z/xvzHav
+define double @test([2 x i32] %val) {
+; CHECK-LABEL: define double @test(
+; CHECK-SAME: [2 x i32] [[VAL:%.*]]) {
+; CHECK-NEXT:    [[VAL_FCA_0_EXTRACT:%.*]] = extractvalue [2 x i32] [[VAL]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double poison to i64
+; CHECK-NEXT:    [[PTR_0_INSERT_EXT:%.*]] = zext i32 [[VAL_FCA_0_EXTRACT]] to i64
+; CHECK-NEXT:    [[PTR_0_INSERT_MASK:%.*]] = and i64 [[TMP1]], -4294967296
+; CHECK-NEXT:    [[PTR_0_INSERT_INSERT:%.*]] = or i64 [[PTR_0_INSERT_MASK]], [[PTR_0_INSERT_EXT]]
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i64 [[PTR_0_INSERT_INSERT]] to double
+; CHECK-NEXT:    [[VAL_FCA_1_EXTRACT:%.*]] = extractvalue [2 x i32] [[VAL]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[TMP2]] to i64
+; CHECK-NEXT:    [[PTR_4_INSERT_EXT:%.*]] = zext i32 [[VAL_FCA_1_EXTRACT]] to i64
+; CHECK-NEXT:    [[PTR_4_INSERT_SHIFT:%.*]] = shl i64 [[PTR_4_INSERT_EXT]], 32
+; CHECK-NEXT:    [[PTR_4_INSERT_MASK:%.*]] = and i64 [[TMP3]], 4294967295
+; CHECK-NEXT:    [[PTR_4_INSERT_INSERT:%.*]] = or i64 [[PTR_4_INSERT_MASK]], [[PTR_4_INSERT_SHIFT]]
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64 [[PTR_4_INSERT_INSERT]] to double
+; CHECK-NEXT:    ret double [[TMP4]]
+;
+  %ptr = alloca double
+  store double poison, ptr %ptr
+  store [2 x i32] %val, ptr %ptr
+  %load = load double, ptr %ptr
+  ret double %load
+}

>From 12f7b930c9dbebede7770efc3d3db559a9e7cb0a Mon Sep 17 00:00:00 2001
From: Junda Liu <Junda.Liu at amd.com>
Date: Thu, 19 Sep 2024 12:16:28 +0800
Subject: [PATCH 2/2] [SROA] Prevent poison propagation in insertInteger()

When inserting an new integer to a larger old integer, freeze the old one first
in case it contains poison, otherwise the insertion still results in poison.
---
 llvm/lib/Transforms/Scalar/SROA.cpp             | 3 +++
 llvm/test/Transforms/SROA/poison-propagation.ll | 6 ++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index d0186da1bc5e22..ace60604a75b7b 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -2519,6 +2519,9 @@ static Value *insertInteger(const DataLayout &DL, IRBuilderTy &IRB, Value *Old,
 
   if (ShAmt || Ty->getBitWidth() < IntTy->getBitWidth()) {
     APInt Mask = ~Ty->getMask().zext(IntTy->getBitWidth()).shl(ShAmt);
+    // Freeze old value first in case it contains poison, otherwise the
+    // combination still results in poison.
+    Old = IRB.CreateFreeze(Old);
     Old = IRB.CreateAnd(Old, Mask, Name + ".mask");
     LLVM_DEBUG(dbgs() << "      masked: " << *Old << "\n");
     V = IRB.CreateOr(Old, V, Name + ".insert");
diff --git a/llvm/test/Transforms/SROA/poison-propagation.ll b/llvm/test/Transforms/SROA/poison-propagation.ll
index 94778235466746..e57547df7b547b 100644
--- a/llvm/test/Transforms/SROA/poison-propagation.ll
+++ b/llvm/test/Transforms/SROA/poison-propagation.ll
@@ -8,14 +8,16 @@ define double @test([2 x i32] %val) {
 ; CHECK-NEXT:    [[VAL_FCA_0_EXTRACT:%.*]] = extractvalue [2 x i32] [[VAL]], 0
 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double poison to i64
 ; CHECK-NEXT:    [[PTR_0_INSERT_EXT:%.*]] = zext i32 [[VAL_FCA_0_EXTRACT]] to i64
-; CHECK-NEXT:    [[PTR_0_INSERT_MASK:%.*]] = and i64 [[TMP1]], -4294967296
+; CHECK-NEXT:    [[TMP6:%.*]] = freeze i64 [[TMP1]]
+; CHECK-NEXT:    [[PTR_0_INSERT_MASK:%.*]] = and i64 [[TMP6]], -4294967296
 ; CHECK-NEXT:    [[PTR_0_INSERT_INSERT:%.*]] = or i64 [[PTR_0_INSERT_MASK]], [[PTR_0_INSERT_EXT]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i64 [[PTR_0_INSERT_INSERT]] to double
 ; CHECK-NEXT:    [[VAL_FCA_1_EXTRACT:%.*]] = extractvalue [2 x i32] [[VAL]], 1
 ; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[TMP2]] to i64
 ; CHECK-NEXT:    [[PTR_4_INSERT_EXT:%.*]] = zext i32 [[VAL_FCA_1_EXTRACT]] to i64
 ; CHECK-NEXT:    [[PTR_4_INSERT_SHIFT:%.*]] = shl i64 [[PTR_4_INSERT_EXT]], 32
-; CHECK-NEXT:    [[PTR_4_INSERT_MASK:%.*]] = and i64 [[TMP3]], 4294967295
+; CHECK-NEXT:    [[TMP5:%.*]] = freeze i64 [[TMP3]]
+; CHECK-NEXT:    [[PTR_4_INSERT_MASK:%.*]] = and i64 [[TMP5]], 4294967295
 ; CHECK-NEXT:    [[PTR_4_INSERT_INSERT:%.*]] = or i64 [[PTR_4_INSERT_MASK]], [[PTR_4_INSERT_SHIFT]]
 ; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64 [[PTR_4_INSERT_INSERT]] to double
 ; CHECK-NEXT:    ret double [[TMP4]]



More information about the llvm-commits mailing list