[llvm] de3cb95 - Fix a bug in memset formation with vectors of non-integral pointers
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 16:11:21 PDT 2020
Author: Philip Reames
Date: 2020-10-01T16:11:11-07:00
New Revision: de3cb9548d77726186db2d384193e0565cb0afc5
URL: https://github.com/llvm/llvm-project/commit/de3cb9548d77726186db2d384193e0565cb0afc5
DIFF: https://github.com/llvm/llvm-project/commit/de3cb9548d77726186db2d384193e0565cb0afc5.diff
LOG: Fix a bug in memset formation with vectors of non-integral pointers
We were converting the non-integral store into a integer store which is not legal.
Added:
Modified:
llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
llvm/test/Transforms/LoopIdiom/non-integral-pointers.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 837ef869ccf0..38094377141f 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -455,11 +455,6 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
if (!SI->isUnordered())
return LegalStoreKind::None;
- // Don't convert stores of non-integral pointer types to memsets (which stores
- // integers).
- if (DL->isNonIntegralPointerType(SI->getValueOperand()->getType()))
- return LegalStoreKind::None;
-
// Avoid merging nontemporal stores.
if (SI->getMetadata(LLVMContext::MD_nontemporal))
return LegalStoreKind::None;
@@ -467,6 +462,11 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
Value *StoredVal = SI->getValueOperand();
Value *StorePtr = SI->getPointerOperand();
+ // Don't convert stores of non-integral pointer types to memsets (which stores
+ // integers).
+ if (DL->isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
+ return LegalStoreKind::None;
+
// Reject stores that are so large that they overflow an unsigned.
// When storing out scalable vectors we bail out for now, since the code
// below currently only works for constant strides.
diff --git a/llvm/test/Transforms/LoopIdiom/non-integral-pointers.ll b/llvm/test/Transforms/LoopIdiom/non-integral-pointers.ll
index 6846e8825394..c8271306535b 100644
--- a/llvm/test/Transforms/LoopIdiom/non-integral-pointers.ll
+++ b/llvm/test/Transforms/LoopIdiom/non-integral-pointers.ll
@@ -3,13 +3,12 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4"
target triple = "x86_64-unknown-linux-gnu"
+; LIR'ing stores of pointers with address space 3 is fine, since
+; they're integral pointers.
define void @f_0(i8 addrspace(3)** %ptr) {
; CHECK-LABEL: @f_0(
; CHECK: call{{.*}}memset
-; LIR'ing stores of pointers with address space 3 is fine, since
-; they're integral pointers.
-
entry:
br label %for.body
@@ -25,13 +24,14 @@ for.end:
ret void
}
+; LIR'ing stores of pointers with address space 4 is not ok, since
+; they're non-integral pointers. NOTE: Zero is special value which
+; can be converted, if we add said handling here, convert this test
+; to use any non-null pointer.
define void @f_1(i8 addrspace(4)** %ptr) {
; CHECK-LABEL: @f_1(
; CHECK-NOT: call{{.*}}memset
-; LIR'ing stores of pointers with address space 4 is not ok, since
-; they're non-integral pointers.
-
entry:
br label %for.body
@@ -46,3 +46,23 @@ for.body:
for.end:
ret void
}
+
+; Same as previous case, but vector of non-integral pointers
+define void @f_2(i8 addrspace(4)** %ptr) {
+; CHECK-LABEL: @f_2(
+; CHECK-NOT: call{{.*}}memset
+entry:
+ br label %for.body
+
+for.body:
+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
+ %arrayidx = getelementptr i8 addrspace(4)*, i8 addrspace(4)** %ptr, i64 %indvar
+ %addr = bitcast i8 addrspace(4)** %arrayidx to <2 x i8 addrspace(4)*>*
+ store <2 x i8 addrspace(4)*> zeroinitializer, <2 x i8 addrspace(4)*>* %addr, align 8
+ %indvar.next = add i64 %indvar, 2
+ %exitcond = icmp eq i64 %indvar.next, 10000
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
More information about the llvm-commits
mailing list