From 0bbcb191e387ee471b16046eb29a4bc9f2666dcf Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Thu, 12 Aug 2021 09:52:24 -0500 Subject: [PATCH] [Attributor][FIX] Guard constant casts with type size checks (cherry picked from commit 5f543919b2646d36f2ddc1424acdd555bfcebe4f) --- lib/Transforms/IPO/Attributor.cpp | 10 ++-- .../Attributor/value-simplify-pointer-info.ll | 60 +++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/IPO/Attributor.cpp b/lib/Transforms/IPO/Attributor.cpp index 5fecbf35fef..91b16ec66ee 100644 --- a/lib/Transforms/IPO/Attributor.cpp +++ b/lib/Transforms/IPO/Attributor.cpp @@ -251,10 +251,12 @@ Value *AA::getWithType(Value &V, Type &Ty) { return Constant::getNullValue(&Ty); if (C->getType()->isPointerTy() && Ty.isPointerTy()) return ConstantExpr::getPointerCast(C, &Ty); - if (C->getType()->isIntegerTy() && Ty.isIntegerTy()) - return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true); - if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy()) - return ConstantExpr::getFPTrunc(C, &Ty, /* OnlyIfReduced */ true); + if (C->getType()->getPrimitiveSizeInBits() >= Ty.getPrimitiveSizeInBits()) { + if (C->getType()->isIntegerTy() && Ty.isIntegerTy()) + return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true); + if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy()) + return ConstantExpr::getFPTrunc(C, &Ty, /* OnlyIfReduced */ true); + } } return nullptr; } diff --git a/test/Transforms/Attributor/value-simplify-pointer-info.ll b/test/Transforms/Attributor/value-simplify-pointer-info.ll index fdb974f003a..80b636951aa 100644 --- a/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -26,6 +26,8 @@ @a1 = internal global i32 zeroinitializer @a2 = internal global i32 zeroinitializer @a3 = internal global i32 undef +@bytes1 = internal global i32 undef +@bytes2 = internal global i32 undef ;. ; CHECK: @[[GLOBALBYTES:[a-zA-Z0-9_$"\\.-]+]] = global [1024 x i8] zeroinitializer, align 16 @@ -48,6 +50,8 @@ ; CHECK: @[[A1:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0 ; CHECK: @[[A2:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0 ; CHECK: @[[A3:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 undef +; CHECK: @[[BYTES1:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 undef +; CHECK: @[[BYTES2:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 undef ;. define void @write_arg(i32* %p, i32 %v) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly @@ -3230,6 +3234,62 @@ end: ret i8 %add } +define i8 @cast_and_load_1() { +; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@cast_and_load_1 +; IS__TUNIT_OPM-SAME: () #[[ATTR4]] { +; IS__TUNIT_OPM-NEXT: store i32 42, i32* @bytes1, align 4 +; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i8, i8* bitcast (i32* @bytes1 to i8*), align 4 +; IS__TUNIT_OPM-NEXT: ret i8 [[L]] +; +; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@cast_and_load_1 +; IS__TUNIT_NPM-SAME: () #[[ATTR2]] { +; IS__TUNIT_NPM-NEXT: store i32 42, i32* @bytes1, align 4 +; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i8, i8* bitcast (i32* @bytes1 to i8*), align 4 +; IS__TUNIT_NPM-NEXT: ret i8 [[L]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_load_1 +; IS__CGSCC____-SAME: () #[[ATTR5]] { +; IS__CGSCC____-NEXT: store i32 42, i32* @bytes1, align 4 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* bitcast (i32* @bytes1 to i8*), align 4 +; IS__CGSCC____-NEXT: ret i8 [[L]] +; + store i32 42, i32* @bytes1 + %bc = bitcast i32* @bytes1 to i8* + %l = load i8, i8* %bc + ret i8 %l +} + +define i64 @cast_and_load_2() { +; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@cast_and_load_2 +; IS__TUNIT_OPM-SAME: () #[[ATTR4]] { +; IS__TUNIT_OPM-NEXT: store i32 42, i32* @bytes2, align 4 +; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i64, i64* bitcast (i32* @bytes2 to i64*), align 4 +; IS__TUNIT_OPM-NEXT: ret i64 [[L]] +; +; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@cast_and_load_2 +; IS__TUNIT_NPM-SAME: () #[[ATTR2]] { +; IS__TUNIT_NPM-NEXT: store i32 42, i32* @bytes2, align 4 +; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i64, i64* bitcast (i32* @bytes2 to i64*), align 4 +; IS__TUNIT_NPM-NEXT: ret i64 [[L]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_load_2 +; IS__CGSCC____-SAME: () #[[ATTR5]] { +; IS__CGSCC____-NEXT: store i32 42, i32* @bytes2, align 4 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i64, i64* bitcast (i32* @bytes2 to i64*), align 4 +; IS__CGSCC____-NEXT: ret i64 [[L]] +; + store i32 42, i32* @bytes2 + %bc = bitcast i32* @bytes2 to i64* + %l = load i64, i64* %bc + ret i64 %l +} + !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2}