[llvm] r233481 - [ConstantFold] Don't fold ppc_fp128 <-> int bitcasts

Hal Finkel hfinkel at anl.gov
Sat Mar 28 09:44:57 PDT 2015


Author: hfinkel
Date: Sat Mar 28 11:44:57 2015
New Revision: 233481

URL: http://llvm.org/viewvc/llvm-project?rev=233481&view=rev
Log:
[ConstantFold] Don't fold ppc_fp128 <-> int bitcasts

PPC_FP128 is really the sum of two consecutive doubles, where the first double
is always stored first in memory, regardless of the target endianness. The
memory layout of i128, however, depends on the target endianness, and so we
can't fold this without target endianness information. As a result, we must not
do this folding in lib/IR/ConstantFold.cpp (it could be done instead in
Analysis/ConstantFolding.cpp, but that's not done now).

Fixes PR23026.

Added:
    llvm/trunk/test/Transforms/SROA/ppcf128-no-fold.ll
Modified:
    llvm/trunk/lib/IR/ConstantFold.cpp

Modified: llvm/trunk/lib/IR/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantFold.cpp?rev=233481&r1=233480&r2=233481&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantFold.cpp (original)
+++ llvm/trunk/lib/IR/ConstantFold.cpp Sat Mar 28 11:44:57 2015
@@ -169,7 +169,8 @@ static Constant *FoldBitCast(Constant *V
       // be the same. Consequently, we just fold to V.
       return V;
 
-    if (DestTy->isFloatingPointTy())
+    // See note below regarding the PPC_FP128 restriction.
+    if (DestTy->isFloatingPointTy() && !DestTy->isPPC_FP128Ty())
       return ConstantFP::get(DestTy->getContext(),
                              APFloat(DestTy->getFltSemantics(),
                                      CI->getValue()));
@@ -179,9 +180,19 @@ static Constant *FoldBitCast(Constant *V
   }
 
   // Handle ConstantFP input: FP -> Integral.
-  if (ConstantFP *FP = dyn_cast<ConstantFP>(V))
+  if (ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
+    // PPC_FP128 is really the sum of two consecutive doubles, where the first
+    // double is always stored first in memory, regardless of the target
+    // endianness. The memory layout of i128, however, depends on the target
+    // endianness, and so we can't fold this without target endianness
+    // information. This should instead be handled by
+    // Analysis/ConstantFolding.cpp
+    if (FP->getType()->isPPC_FP128Ty())
+      return nullptr;
+
     return ConstantInt::get(FP->getContext(),
                             FP->getValueAPF().bitcastToAPInt());
+  }
 
   return nullptr;
 }

Added: llvm/trunk/test/Transforms/SROA/ppcf128-no-fold.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SROA/ppcf128-no-fold.ll?rev=233481&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SROA/ppcf128-no-fold.ll (added)
+++ llvm/trunk/test/Transforms/SROA/ppcf128-no-fold.ll Sat Mar 28 11:44:57 2015
@@ -0,0 +1,36 @@
+; RUN: opt < %s -sroa -S | FileCheck %s 
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+%struct.ld2 = type { [2 x ppc_fp128] }
+declare void @bar(i8*, [2 x i128])
+
+define void @foo(i8* %v) #0 {
+entry:
+  %v.addr = alloca i8*, align 8
+  %z = alloca %struct.ld2, align 16
+  store i8* %v, i8** %v.addr, align 8
+  %dat = getelementptr inbounds %struct.ld2, %struct.ld2* %z, i32 0, i32 0
+  %arrayidx = getelementptr inbounds [2 x ppc_fp128], [2 x ppc_fp128]* %dat, i32 0, i64 0
+  store ppc_fp128 0xM403B0000000000000000000000000000, ppc_fp128* %arrayidx, align 16
+  %dat1 = getelementptr inbounds %struct.ld2, %struct.ld2* %z, i32 0, i32 0
+  %arrayidx2 = getelementptr inbounds [2 x ppc_fp128], [2 x ppc_fp128]* %dat1, i32 0, i64 1
+  store ppc_fp128 0xM4093B400000000000000000000000000, ppc_fp128* %arrayidx2, align 16
+  %0 = load i8*, i8** %v.addr, align 8
+  %coerce.dive = getelementptr %struct.ld2, %struct.ld2* %z, i32 0, i32 0
+  %1 = bitcast [2 x ppc_fp128]* %coerce.dive to [2 x i128]*
+  %2 = load [2 x i128], [2 x i128]* %1, align 1
+  call void @bar(i8* %0, [2 x i128] %2)
+  ret void
+}
+
+; CHECK-LABEL: @foo
+; CHECK-NOT: i128 4628293042053316608
+; CHECK-NOT: i128 4653260752096854016
+; CHECK-DAG: i128 bitcast (ppc_fp128 0xM403B0000000000000000000000000000 to i128)
+; CHECK-DAG: i128 bitcast (ppc_fp128 0xM4093B400000000000000000000000000 to i128)
+; CHECK: call void @bar(i8* %v, [2 x i128]
+; CHECK: ret void
+
+attributes #0 = { nounwind }
+





More information about the llvm-commits mailing list