From 639388a05f25772fb23eea5b1045e7df83bcfaa7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Aug 2022 16:13:09 +0200 Subject: [PATCH] [RelLookupTableConverter] Bail on invalid pointer size (x32) The RelLookupTableConverter pass currently only supports 64-bit pointers. This is currently enforced using an isArch64Bit() check on the target triple. However, we consider x32 to be a 64-bit target, even though the pointers are 32-bit. (And independently of that specific example, there may be address spaces with different pointer sizes.) As such, add an additional guard for the size of the pointers that are actually part of the lookup table. Differential Revision: https://reviews.llvm.org/D131399 (cherry picked from commit 4ac00789e1b30145ec3cacc4b2a66cb755ff9e4a) --- .../Utils/RelLookupTableConverter.cpp | 8 +++++-- .../RelLookupTableConverter/X86/gnux32.ll | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/RelLookupTableConverter/X86/gnux32.ll diff --git a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp index 92642745068258..c9ff94dc9744fa 100644 --- a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp +++ b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp @@ -57,11 +57,15 @@ static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) { return false; ConstantArray *Array = dyn_cast(GV.getInitializer()); - // If values are not pointers, do not generate a relative lookup table. - if (!Array || !Array->getType()->getElementType()->isPointerTy()) + if (!Array) return false; + // If values are not 64-bit pointers, do not generate a relative lookup table. const DataLayout &DL = M.getDataLayout(); + Type *ElemType = Array->getType()->getElementType(); + if (!ElemType->isPointerTy() || DL.getPointerTypeSizeInBits(ElemType) != 64) + return false; + for (const Use &Op : Array->operands()) { Constant *ConstOp = cast(&Op); GlobalValue *GVOp; diff --git a/llvm/test/Transforms/RelLookupTableConverter/X86/gnux32.ll b/llvm/test/Transforms/RelLookupTableConverter/X86/gnux32.ll new file mode 100644 index 00000000000000..0088067e18eaf6 --- /dev/null +++ b/llvm/test/Transforms/RelLookupTableConverter/X86/gnux32.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=rel-lookup-table-converter -relocation-model=pic -S | FileCheck %s +; REQUIRES: x86-registered-target + +target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnux32" + +@a = internal constant i32 0, align 4 +@b = internal constant i32 0, align 4 +@c = internal constant i32 0, align 4 + +@table = private unnamed_addr constant [3 x ptr] [ptr @a, ptr @b, ptr @c] + +define ptr @test(i32 %cond) { +; CHECK-LABEL: @test( +; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr @table, i32 0, i32 [[COND:%.*]] +; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load ptr, ptr [[SWITCH_GEP]], align 8 +; CHECK-NEXT: ret ptr [[SWITCH_LOAD]] +; + %switch.gep = getelementptr inbounds [3 x ptr], ptr @table, i32 0, i32 %cond + %switch.load = load ptr, ptr %switch.gep, align 8 + ret ptr %switch.load +}