[PATCH] D144057: [GVN] permit GVN of non-local loads for ASAN unless undef is produced

Nick Desaulniers via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 14 16:27:43 PST 2023


nickdesaulniers updated this revision to Diff 497479.
nickdesaulniers edited the summary of this revision.
nickdesaulniers added a comment.

- include sha of original fix in commit message


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144057/new/

https://reviews.llvm.org/D144057

Files:
  llvm/lib/Transforms/Scalar/GVN.cpp
  llvm/test/Transforms/GVN/no_speculative_loads_with_asan.ll


Index: llvm/test/Transforms/GVN/no_speculative_loads_with_asan.ll
===================================================================
--- llvm/test/Transforms/GVN/no_speculative_loads_with_asan.ll
+++ llvm/test/Transforms/GVN/no_speculative_loads_with_asan.ll
@@ -3,7 +3,7 @@
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 declare noalias ptr @_Znam(i64) #1
 
-; Load of %i8 is an out of bounds load, which is folded to poison, which allows
+; Load of %i8 is an out of bounds load, which is folded to undef, which allows
 ; us to elide the phi.
 define i32 @TestNoAsan() {
 ; CHECK-LABEL: @TestNoAsan(
@@ -158,27 +158,25 @@
 ; CHECK-NEXT:    [[TOBOOL_I:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    br i1 [[TOBOOL_I]], label [[WHILE_BODY_I:%.*]], label [[NODE_FROM_NDEV_IP_EXIT:%.*]]
 ; CHECK:       while.body.i:
-; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[SA_ADDR_I]], align 8
-; CHECK-NEXT:    store ptr [[TMP2]], ptr [[SA_ADDR_I_I]], align 8
-; CHECK-NEXT:    [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 2
-; CHECK-NEXT:    [[TOBOOL_I_I:%.*]] = icmp ne i16 [[TMP3]], 0
+; CHECK-NEXT:    store ptr [[NEIGH_SOCK_4]], ptr [[SA_ADDR_I_I]], align 8
+; CHECK-NEXT:    [[TMP2:%.*]] = load i16, ptr [[NEIGH_SOCK_4]], align 2
+; CHECK-NEXT:    [[TOBOOL_I_I:%.*]] = icmp ne i16 [[TMP2]], 0
 ; CHECK-NEXT:    br i1 [[TOBOOL_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
 ; CHECK:       if.then.i.i:
-; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[SA_ADDR_I_I]], align 8
-; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
-; CHECK-NEXT:    [[CONV_I_I:%.*]] = sext i32 [[TMP5]] to i64
-; CHECK-NEXT:    [[CALL_I_I:%.*]] = call i32 @_Z6memcmpPvS_m(ptr noundef [[TMP4]], ptr noundef @compare_netdev_and_ip_sb_0, i64 noundef [[CONV_I_I]])
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[NEIGH_SOCK_4]], align 4
+; CHECK-NEXT:    [[CONV_I_I:%.*]] = sext i32 [[TMP3]] to i64
+; CHECK-NEXT:    [[CALL_I_I:%.*]] = call i32 @_Z6memcmpPvS_m(ptr noundef [[NEIGH_SOCK_4]], ptr noundef @compare_netdev_and_ip_sb_0, i64 noundef [[CONV_I_I]])
 ; CHECK-NEXT:    store i32 [[CALL_I_I]], ptr [[RETVAL_I_I]], align 4
 ; CHECK-NEXT:    br label [[COMPARE_NETDEV_AND_IP_EXIT_I:%.*]]
 ; CHECK:       if.end.i.i:
-; CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr @ipv6_addr_cmp_a1, align 8
-; CHECK-NEXT:    [[CALL2_I_I:%.*]] = call i32 @_Z6memcmpPvS_m(ptr noundef [[TMP6]], ptr noundef @ipv6_addr_cmp_a2, i64 noundef 4)
+; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr @ipv6_addr_cmp_a1, align 8
+; CHECK-NEXT:    [[CALL2_I_I:%.*]] = call i32 @_Z6memcmpPvS_m(ptr noundef [[TMP4]], ptr noundef @ipv6_addr_cmp_a2, i64 noundef 4)
 ; CHECK-NEXT:    store i32 [[CALL2_I_I]], ptr @compare_netdev_and_ip___trans_tmp_1, align 4
 ; CHECK-NEXT:    store i32 [[CALL2_I_I]], ptr [[RETVAL_I_I]], align 4
 ; CHECK-NEXT:    br label [[COMPARE_NETDEV_AND_IP_EXIT_I]]
 ; CHECK:       compare_netdev_and_ip.exit.i:
-; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[RETVAL_I_I]], align 4
-; CHECK-NEXT:    store i32 [[TMP7]], ptr @node_from_ndev_ip_data, align 4
+; CHECK-NEXT:    [[TMP5:%.*]] = phi i32 [ [[CALL2_I_I]], [[IF_END_I_I]] ], [ [[CALL_I_I]], [[IF_THEN_I_I]] ]
+; CHECK-NEXT:    store i32 [[TMP5]], ptr @node_from_ndev_ip_data, align 4
 ; CHECK-NEXT:    br label [[WHILE_COND_I]]
 ; CHECK:       node_from_ndev_ip.exit:
 ; CHECK-NEXT:    br label [[IF_END]]
Index: llvm/lib/Transforms/Scalar/GVN.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/GVN.cpp
+++ llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1717,13 +1717,6 @@
 /// Attempt to eliminate a load whose dependencies are
 /// non-local by performing PHI construction.
 bool GVNPass::processNonLocalLoad(LoadInst *Load) {
-  // non-local speculations are not allowed under asan.
-  if (Load->getParent()->getParent()->hasFnAttribute(
-          Attribute::SanitizeAddress) ||
-      Load->getParent()->getParent()->hasFnAttribute(
-          Attribute::SanitizeHWAddress))
-    return false;
-
   // Step 1: Find the non-local dependencies of the load.
   LoadDepVect Deps;
   MD->getNonLocalPointerDependency(Load, Deps);
@@ -1773,6 +1766,16 @@
 
     // Perform PHI construction.
     Value *V = ConstructSSAForLoadSet(Load, ValuesPerBlock, *this);
+
+    // If a non-local load would result in producing undef, don't fold away
+    // control flow. We want the sanitizers to help report this case.
+    if (isa<UndefValue>(V)) {
+      Function *F = Load->getParent()->getParent();
+      if (F->hasFnAttribute(Attribute::SanitizeAddress) ||
+          F->hasFnAttribute(Attribute::SanitizeHWAddress))
+        return false;
+    }
+
     Load->replaceAllUsesWith(V);
 
     if (isa<PHINode>(V))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144057.497479.patch
Type: text/x-patch
Size: 4713 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230215/54e81660/attachment.bin>


More information about the llvm-commits mailing list