[llvm-commits] [llvm] r166049 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/trunc-fp2int.ll

Michael Liao michael.liao at intel.com
Wed Oct 17 15:36:09 PDT 2012


It seems to me this behavior is little hairy regarding to C standard and
LLVM langref.

For C, it defines that, when an integer is casted to a signed integer
and the value cannot be represented in it; either the result is
implementation-defined or an implementation-defined signed is raised.
(ref section 6.3.1.3)

Based on this definition, the cast in
SingleSource/UnitTests/FloatPrecision.c

  printf("%x\n", (int)(unsigned long long)(X*2147483647));

falls into this implementation-defined behavior (float -> u64 -> i32 and
that product is out of range of i32), somewhat undefined behavior.

But, 'trunc' in LLVM langref is defined as the behavior of casting into
unsigned integer and it's very difficult to tell whether an integer is
signed or unsigned in general. I will revert this commit.

Thanks
- Michael


On Wed, 2012-10-17 at 14:08 -0700, Michael Liao wrote:
> Sure, I am looking into it now. - Michael
> 
> On Wed, 2012-10-17 at 13:57 -0700, Daniel Dunbar wrote:
> > Hi Michael,
> > 
> > Are you sure about this transformation? It breaks
> > SingleSource/UnitTests/FloatPrecision.c on ARMv7/O0/-g.
> > 
> > Can you take a look? The expected output of the test is:
> > --
> > 2147483648000.000000
> > 0
> > --
> > but with your patch the executable built with Clang at -O0 generates:
> > --
> > 2147483648000.000000
> > ffffffff
> > --
> > 
> > Thanks,
> >  - Daniel
> > 
> > On Tue, Oct 16, 2012 at 12:38 PM, Michael Liao <michael.liao at intel.com> wrote:
> > > Author: hliao
> > > Date: Tue Oct 16 14:38:35 2012
> > > New Revision: 166049
> > >
> > > URL: http://llvm.org/viewvc/llvm-project?rev=166049&view=rev
> > > Log:
> > > Teach DAG combine to fold (trunc (fptoXi x)) to (fptoXi x)
> > >
> > >
> > > Added:
> > >     llvm/trunk/test/CodeGen/X86/trunc-fp2int.ll
> > > Modified:
> > >     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> > >
> > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=166049&r1=166048&r2=166049&view=diff
> > > ==============================================================================
> > > --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> > > +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Oct 16 14:38:35 2012
> > > @@ -5308,6 +5308,52 @@
> > >      if (Reduced.getNode())
> > >        return Reduced;
> > >    }
> > > +  // fold (trunc (fptoXi x)) -> (smaller fptoXi x)
> > > +  if ((N0.getOpcode() == ISD::FP_TO_UINT ||
> > > +       N0.getOpcode() == ISD::FP_TO_SINT) && !LegalTypes)
> > > +    return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, N0.getOperand(0));
> > > +  // fold (trunc (concat ... x ...)) -> (concat ..., (trunc x), ...)),
> > > +  // where ... are all 'undef'.
> > > +  if (N0.getOpcode() == ISD::CONCAT_VECTORS && !LegalTypes) {
> > > +    SmallVector<EVT, 8> VTs;
> > > +    SDValue V;
> > > +    unsigned Idx = 0;
> > > +    unsigned NumDefs = 0;
> > > +
> > > +    for (unsigned i = 0, e = N0.getNumOperands(); i != e; ++i) {
> > > +      SDValue X = N0.getOperand(i);
> > > +      if (X.getOpcode() != ISD::UNDEF) {
> > > +        V = X;
> > > +        Idx = i;
> > > +        NumDefs++;
> > > +      }
> > > +      // Stop if more than one members are non-undef.
> > > +      if (NumDefs > 1)
> > > +        break;
> > > +      VTs.push_back(EVT::getVectorVT(*DAG.getContext(),
> > > +                                     VT.getVectorElementType(),
> > > +                                     X.getValueType().getVectorNumElements()));
> > > +    }
> > > +
> > > +    if (NumDefs == 0)
> > > +      return DAG.getUNDEF(VT);
> > > +
> > > +    if (NumDefs == 1) {
> > > +      assert(V.getNode() && "The single defined operand is empty!");
> > > +      SmallVector<SDValue, 8> Opnds;
> > > +      for (unsigned i = 0, e = VTs.size(); i != e; ++i) {
> > > +        if (i != Idx) {
> > > +          Opnds.push_back(DAG.getUNDEF(VTs[i]));
> > > +          continue;
> > > +        }
> > > +        SDValue NV = DAG.getNode(ISD::TRUNCATE, V.getDebugLoc(), VTs[i], V);
> > > +        AddToWorkList(NV.getNode());
> > > +        Opnds.push_back(NV);
> > > +      }
> > > +      return DAG.getNode(ISD::CONCAT_VECTORS, N->getDebugLoc(), VT,
> > > +                         &Opnds[0], Opnds.size());
> > > +    }
> > > +  }
> > >
> > >    // Simplify the operands using demanded-bits information.
> > >    if (!VT.isVector() &&
> > >
> > > Added: llvm/trunk/test/CodeGen/X86/trunc-fp2int.ll
> > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/trunc-fp2int.ll?rev=166049&view=auto
> > > ==============================================================================
> > > --- llvm/trunk/test/CodeGen/X86/trunc-fp2int.ll (added)
> > > +++ llvm/trunk/test/CodeGen/X86/trunc-fp2int.ll Tue Oct 16 14:38:35 2012
> > > @@ -0,0 +1,18 @@
> > > +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=corei7 | FileCheck %s
> > > +
> > > +define <4 x i8> @bar(<4 x float> %in) nounwind readnone alwaysinline {
> > > +  %1 = fptoui <4 x float> %in to <4 x i8>
> > > +  ret <4 x i8> %1
> > > +; CHECK: bar
> > > +; CHECK: cvttps2dq
> > > +}
> > > +define <4 x i8> @foo(<4 x float> %in) nounwind readnone alwaysinline {
> > > +  %1 = fptoui <4 x float> %in to <4 x i32>
> > > +  %2 = trunc <4 x i32> %1 to <4 x i16>
> > > +  %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
> > > +  %4 = trunc <8 x i16> %3 to <8 x i8>
> > > +  %5 = shufflevector <8 x i8> %4, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
> > > +  ret <4 x i8> %5
> > > +; CHECK: foo
> > > +; CHECK: cvttps2dq
> > > +}
> > >
> > >
> > > _______________________________________________
> > > llvm-commits mailing list
> > > llvm-commits at cs.uiuc.edu
> > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list