[Local] Handle size mismatch between pointer/int in copyRangeMetadata()
authorNikita Popov <npopov@redhat.com>
Fri, 31 Mar 2023 10:18:02 +0000 (12:18 +0200)
committerNikita Popov <npopov@redhat.com>
Fri, 31 Mar 2023 10:20:34 +0000 (12:20 +0200)
SROA may convert a wide integer load into a narrow pointer load,
make sure we don't crash. It would not be legal to transfer the
metadata in this case.

llvm/lib/Transforms/Utils/Local.cpp
llvm/test/Transforms/SROA/preserve-metadata.ll

index 47088aa..3fb0d0c 100644 (file)
@@ -2948,7 +2948,8 @@ void llvm::copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI,
     return;
 
   unsigned BitWidth = DL.getPointerTypeSizeInBits(NewTy);
-  if (!getConstantRangeFromMetadata(*N).contains(APInt(BitWidth, 0))) {
+  if (BitWidth == OldLI.getType()->getScalarSizeInBits() &&
+      !getConstantRangeFromMetadata(*N).contains(APInt(BitWidth, 0))) {
     MDNode *NN = MDNode::get(OldLI.getContext(), std::nullopt);
     NewLI.setMetadata(LLVMContext::MD_nonnull, NN);
   }
index 6910a4c..ba8fbc8 100644 (file)
@@ -128,6 +128,24 @@ entry:
   ret ptr %load
 }
 
+define i128 @load_i128_to_load_ptr() {
+; CHECK-LABEL: @load_i128_to_load_ptr(
+; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr null to i64
+; CHECK-NEXT:    [[A_SROA_2_0_INSERT_EXT:%.*]] = zext i64 undef to i128
+; CHECK-NEXT:    [[A_SROA_2_0_INSERT_SHIFT:%.*]] = shl i128 [[A_SROA_2_0_INSERT_EXT]], 64
+; CHECK-NEXT:    [[A_SROA_2_0_INSERT_MASK:%.*]] = and i128 undef, 18446744073709551615
+; CHECK-NEXT:    [[A_SROA_2_0_INSERT_INSERT:%.*]] = or i128 [[A_SROA_2_0_INSERT_MASK]], [[A_SROA_2_0_INSERT_SHIFT]]
+; CHECK-NEXT:    [[A_SROA_0_0_INSERT_EXT:%.*]] = zext i64 [[TMP1]] to i128
+; CHECK-NEXT:    [[A_SROA_0_0_INSERT_MASK:%.*]] = and i128 [[A_SROA_2_0_INSERT_INSERT]], -18446744073709551616
+; CHECK-NEXT:    [[A_SROA_0_0_INSERT_INSERT:%.*]] = or i128 [[A_SROA_0_0_INSERT_MASK]], [[A_SROA_0_0_INSERT_EXT]]
+; CHECK-NEXT:    ret i128 [[A_SROA_0_0_INSERT_INSERT]]
+;
+  %a = alloca i128
+  store ptr null, ptr %a
+  %v = load i128, ptr %a, !range !{i128 1, i128 0}
+  ret i128 %v
+}
+
 !0 = !{}
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
 ; CHECK-MODIFY-CFG: {{.*}}