From aeb36ae0f4cbc5fb1d01921d89a80d62ccc2f058 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 18 Dec 2021 20:40:42 +0100 Subject: [PATCH] Revert "[ConstantFolding] Unify handling of load from uniform value" This reverts commit 9fd4f80e33a4ae4567483819646650f5735286e2. This breaks SingleSource/Regression/C/gcc-c-torture/execute/pr19687.c in test-suite. Either the test is incorrect, or clang is generating incorrect union initialization code. I've submitted https://reviews.llvm.org/D115994 to fix the test, assuming my interpretation is correct. Reverting this in the meantime as it may take some time to resolve. --- clang/test/CodeGen/aapcs-align.cpp | 4 +- llvm/include/llvm/Analysis/ConstantFolding.h | 6 --- llvm/lib/Analysis/ConstantFolding.cpp | 49 +++++++++++----------- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 5 +-- llvm/test/Transforms/GlobalOpt/x86_mmx_load.ll | 12 ------ .../Transforms/InstSimplify/ConstProp/loads.ll | 13 ------ 6 files changed, 29 insertions(+), 60 deletions(-) delete mode 100644 llvm/test/Transforms/GlobalOpt/x86_mmx_load.ll diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 8543081..8950908 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) -// CHECK: call void @f6m(i32 1, i32 2, i32 3, i32 4, i32 5, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call void @f6(i32 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6m(i32 1, i32 2, i32 3, i32 4, i32 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) // CHECK: declare void @f6(i32, [4 x i32]) // CHECK: declare void @f6m(i32, i32, i32, i32, i32, [4 x i32]) } diff --git a/llvm/include/llvm/Analysis/ConstantFolding.h b/llvm/include/llvm/Analysis/ConstantFolding.h index 3b3a178..45fb879 100644 --- a/llvm/include/llvm/Analysis/ConstantFolding.h +++ b/llvm/include/llvm/Analysis/ConstantFolding.h @@ -148,12 +148,6 @@ Constant *ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, Constant *ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, const DataLayout &DL); -/// If C is a uniform value where all bits are the same (either all zero, all -/// ones, all undef or all poison), return the corresponding uniform value in -/// the new type. If the value is not uniform or the result cannot be -/// represented, return null. -Constant *ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty); - /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the /// constant expression, or null if something is funny and we can't decide. diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 3fc24d8..fcf4be4 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -106,8 +106,11 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) { "Invalid constantexpr bitcast!"); // Catch the obvious splat cases. - if (Constant *Res = ConstantFoldLoadFromUniformValue(C, DestTy)) - return Res; + if (C->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy()) + return Constant::getNullValue(DestTy); + if (C->isAllOnesValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy() && + !DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types! + return Constant::getAllOnesValue(DestTy); if (auto *VTy = dyn_cast(C->getType())) { // Handle a vector->scalar integer/fp cast. @@ -359,8 +362,16 @@ Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy, // Catch the obvious splat cases (since all-zeros can coerce non-integral // pointers legally). - if (Constant *Res = ConstantFoldLoadFromUniformValue(C, DestTy)) - return Res; + if (C->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy()) + return Constant::getNullValue(DestTy); + if (C->isAllOnesValue() && + (DestTy->isIntegerTy() || DestTy->isFloatingPointTy() || + DestTy->isVectorTy()) && + !DestTy->isX86_AMXTy() && !DestTy->isX86_MMXTy() && + !DestTy->isPtrOrPtrVectorTy()) + // Get ones when the input is trivial, but + // only for supported types inside getAllOnesValue. + return Constant::getAllOnesValue(DestTy); // If the type sizes are the same and a cast is legal, just directly // cast the constant. @@ -693,13 +704,16 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, Offset, DL)) return Result; - // If this load comes from anywhere in a uniform constant global, the value - // is always the same, regardless of the loaded offset. - if (auto *GV = dyn_cast(getUnderlyingObject(C))) - if (GV->isConstant() && GV->hasDefinitiveInitializer()) - if (Constant *Res = - ConstantFoldLoadFromUniformValue(GV->getInitializer(), Ty)) - return Res; + // If this load comes from anywhere in a constant global, and if the global + // is all undef or zero, we know what it loads. + if (auto *GV = dyn_cast(getUnderlyingObject(C))) { + if (GV->isConstant() && GV->hasDefinitiveInitializer()) { + if (GV->getInitializer()->isNullValue()) + return Constant::getNullValue(Ty); + if (isa(GV->getInitializer())) + return UndefValue::get(Ty); + } + } return nullptr; } @@ -710,19 +724,6 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, return ConstantFoldLoadFromConstPtr(C, Ty, Offset, DL); } -Constant *llvm::ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty) { - if (isa(C)) - return PoisonValue::get(Ty); - if (isa(C)) - return UndefValue::get(Ty); - if (C->isNullValue() && !Ty->isX86_MMXTy() && !Ty->isX86_AMXTy()) - return Constant::getNullValue(Ty); - if (C->isAllOnesValue() && - (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy())) - return Constant::getAllOnesValue(Ty); - return nullptr; -} - namespace { /// One of Op0/Op1 is a constant expression. diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 801333b..c3aab61 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -305,9 +305,8 @@ static bool CleanupConstantGlobalUsers(GlobalVariable *GV, else if (auto *LI = dyn_cast(U)) { // A load from zeroinitializer is always zeroinitializer, regardless of // any applied offset. - if (Constant *Res = - ConstantFoldLoadFromUniformValue(Init, LI->getType())) { - LI->replaceAllUsesWith(Res); + if (Init->isNullValue()) { + LI->replaceAllUsesWith(Constant::getNullValue(LI->getType())); EraseFromParent(LI); continue; } diff --git a/llvm/test/Transforms/GlobalOpt/x86_mmx_load.ll b/llvm/test/Transforms/GlobalOpt/x86_mmx_load.ll deleted file mode 100644 index 3b1fa8c..0000000 --- a/llvm/test/Transforms/GlobalOpt/x86_mmx_load.ll +++ /dev/null @@ -1,12 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -globalopt < %s | FileCheck %s - -@m64 = internal global <1 x i64> zeroinitializer - -define i32 @load_mmx() { -; CHECK-LABEL: @load_mmx( -; CHECK-NEXT: ret i32 0 -; - %temp = load x86_mmx, x86_mmx* bitcast (<1 x i64>* @m64 to x86_mmx*) - ret i32 0 -} diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll index a825ff6..0938078 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll @@ -280,16 +280,3 @@ define { i64, i64 } @test_load_struct() { %v = load { i64, i64 }, { i64, i64 }* @g3 ret { i64, i64 } %v } - -@m64 = internal constant [2 x i64] zeroinitializer -@idx = external global i32 - -; This should not try to create an x86_mmx null value. -define x86_mmx @load_mmx() { -; CHECK-LABEL: @load_mmx( -; CHECK-NEXT: [[TEMP:%.*]] = load x86_mmx, x86_mmx* bitcast (i64* getelementptr ([2 x i64], [2 x i64]* @m64, i64 0, i64 ptrtoint (i32* @idx to i64)) to x86_mmx*), align 8 -; CHECK-NEXT: ret x86_mmx [[TEMP]] -; - %temp = load x86_mmx, x86_mmx* bitcast (i64* getelementptr ([2 x i64], [2 x i64]* @m64, i64 0, i64 ptrtoint (i32* @idx to i64)) to x86_mmx*) - ret x86_mmx %temp -} -- 2.7.4