[llvm] [GVN] Freeze value if `undef` when forwarding local memset to loads (PR #91376)

via llvm-commits llvm-commits at lists.llvm.org
Tue May 7 11:32:43 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Antonio Frighetto (antoniofrighetto)

<details>
<summary>Changes</summary>

A miscompilation issue has been addressed with refined checking.

Proof: https://alive2.llvm.org/ce/z/3JVV7C.

---
Full diff: https://github.com/llvm/llvm-project/pull/91376.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Utils/VNCoercion.cpp (+6-3) 
- (modified) llvm/test/Transforms/GVN/PRE/rle.ll (+2-1) 


``````````diff
diff --git a/llvm/lib/Transforms/Utils/VNCoercion.cpp b/llvm/lib/Transforms/Utils/VNCoercion.cpp
index 7a597da2bc515..a085b1844a012 100644
--- a/llvm/lib/Transforms/Utils/VNCoercion.cpp
+++ b/llvm/lib/Transforms/Utils/VNCoercion.cpp
@@ -370,10 +370,13 @@ Value *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
     // memset(P, 'x', 1234) -> splat('x'), even if x is a variable, and
     // independently of what the offset is.
     Value *Val = MSI->getValue();
+    Value *FrozenVal = Val;
+    if (!isGuaranteedNotToBeUndef(Val))
+      FrozenVal = Builder.CreateFreeze(Val, Val->getName() + ".frozen");
     if (LoadSize != 1)
-      Val =
-          Builder.CreateZExtOrBitCast(Val, IntegerType::get(Ctx, LoadSize * 8));
-    Value *OneElt = Val;
+      Val = Builder.CreateZExtOrBitCast(FrozenVal,
+                                        IntegerType::get(Ctx, LoadSize * 8));
+    Value *OneElt = FrozenVal;
 
     // Splat the value out to the right number of bits.
     for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
diff --git a/llvm/test/Transforms/GVN/PRE/rle.ll b/llvm/test/Transforms/GVN/PRE/rle.ll
index fd4a9a081eab3..89fbfb1b800ec 100644
--- a/llvm/test/Transforms/GVN/PRE/rle.ll
+++ b/llvm/test/Transforms/GVN/PRE/rle.ll
@@ -201,7 +201,8 @@ define float @memset_to_float_local(ptr %A, i8 %Val) nounwind ssp {
 ; CHECK-LABEL: @memset_to_float_local(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    tail call void @llvm.memset.p0.i64(ptr [[A:%.*]], i8 [[VAL:%.*]], i64 400, i1 false)
-; CHECK-NEXT:    [[TMP0:%.*]] = zext i8 [[VAL]] to i32
+; CHECK-NEXT:    [[VAL_FROZEN:%.*]] = freeze i8 [[VAL]]
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i8 [[VAL_FROZEN]] to i32
 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[TMP0]], 8
 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP0]], [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP2]], 16

``````````

</details>


https://github.com/llvm/llvm-project/pull/91376


More information about the llvm-commits mailing list