From c3bbf579ae3ddc67bfd06f12496ae24af70e0ba0 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 20 Apr 2009 16:03:21 +0000 Subject: [PATCH] These bitfields were being miscompiled on some 64 bit platforms when building with optimization. So replace them by a hand-coded implementation. This fixes PR3822. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69597 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/InlineCost.h | 38 +++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/include/llvm/Transforms/Utils/InlineCost.h b/include/llvm/Transforms/Utils/InlineCost.h index d78a0f0818e..f275b760824 100644 --- a/include/llvm/Transforms/Utils/InlineCost.h +++ b/include/llvm/Transforms/Utils/InlineCost.h @@ -16,6 +16,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include +#include #include #include @@ -37,26 +38,41 @@ namespace llvm { Never }; - int Cost : 30; - unsigned Type : 2; + // This is a do-it-yourself implementation of + // int Cost : 30; + // unsigned Type : 2; + // We used to use bitfields, but they were sometimes miscompiled (PR3822). + enum { TYPE_BITS = 2 }; + enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS }; + unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS; - InlineCost(int C, int T) : Cost(C), Type(T) { - assert(Cost == C && "Cost exceeds InlineCost precision"); + Kind getType() const { + return Kind(TypedCost >> COST_BITS); + } + + int getCost() const { + // Sign-extend the bottom COST_BITS bits. + return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS; + } + + InlineCost(int C, int T) { + TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS); + assert(getCost() == C && "Cost exceeds InlineCost precision"); } public: static InlineCost get(int Cost) { return InlineCost(Cost, Value); } static InlineCost getAlways() { return InlineCost(0, Always); } - static InlineCost getNever() { return InlineCost(0, Never); } + static InlineCost getNever() { return InlineCost(0, Never); } - bool isVariable() const { return Type == Value; } - bool isAlways() const { return Type == Always; } - bool isNever() const { return Type == Never; } + bool isVariable() const { return getType() == Value; } + bool isAlways() const { return getType() == Always; } + bool isNever() const { return getType() == Never; } /// getValue() - Return a "variable" inline cost's amount. It is /// an error to call this on an "always" or "never" InlineCost. - int getValue() const { - assert(Type == Value && "Invalid access of InlineCost"); - return Cost; + int getValue() const { + assert(getType() == Value && "Invalid access of InlineCost"); + return getCost(); } }; -- 2.34.1