diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -769,10 +769,12 @@ if (!CS) return false; - uint64_t TypeSize = DL.getTypeAllocSize(AI->getAllocatedType()); + TypeSize TS = DL.getTypeAllocSize(AI->getAllocatedType()); + if (TS.isScalable()) + return false; // Make sure that, even if the multiplication below would wrap as an // uint64_t, we still do the right thing. - if ((CS->getValue().zext(128) * APInt(128, TypeSize)).ugt(MaxSize)) + if ((CS->getValue().zext(128) * APInt(128, TS.getFixedSize())).ugt(MaxSize)) return false; continue; } diff --git a/llvm/test/Transforms/InstCombine/gep-object-size-less-than-or-equal-typesize.ll b/llvm/test/Transforms/InstCombine/gep-object-size-less-than-or-equal-typesize.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/gep-object-size-less-than-or-equal-typesize.ll @@ -0,0 +1,17 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -instcombine -S | FileCheck %s + +define i8 @foo( %x, i64 %idx) { +; CHECK-LABEL: @foo( +; CHECK-NEXT: [[A:%.*]] = alloca , align 1 +; CHECK-NEXT: store [[X:%.*]], ptr [[A]], align 1 +; CHECK-NEXT: [[B:%.*]] = getelementptr i8, ptr [[A]], i64 [[IDX:%.*]] +; CHECK-NEXT: [[C:%.*]] = load i8, ptr [[B]], align 1 +; CHECK-NEXT: ret i8 [[C]] +; + %a = alloca + store %x, ptr %a + %b = getelementptr i8, ptr %a, i64 %idx + %c = load i8, ptr %b + ret i8 %c +}