@@ -1741,6 +1741,63 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
1741
1741
Builder.CreateMemSet (Dest, ByteVal, SizeVal, false );
1742
1742
return RValue::get (Dest.getPointer ());
1743
1743
}
1744
+ case Builtin::BI__builtin_wmemcmp: {
1745
+ // The MSVC runtime library does not provide a definition of wmemcmp, so we
1746
+ // need an inline implementation.
1747
+ if (!getTarget ().getTriple ().isOSMSVCRT ())
1748
+ break ;
1749
+
1750
+ llvm::Type *WCharTy = ConvertType (getContext ().WCharTy );
1751
+
1752
+ Value *Dst = EmitScalarExpr (E->getArg (0 ));
1753
+ Value *Src = EmitScalarExpr (E->getArg (1 ));
1754
+ Value *Size = EmitScalarExpr (E->getArg (2 ));
1755
+
1756
+ BasicBlock *Entry = Builder.GetInsertBlock ();
1757
+ BasicBlock *CmpGT = createBasicBlock (" wmemcmp.gt" );
1758
+ BasicBlock *CmpLT = createBasicBlock (" wmemcmp.lt" );
1759
+ BasicBlock *Next = createBasicBlock (" wmemcmp.next" );
1760
+ BasicBlock *Exit = createBasicBlock (" wmemcmp.exit" );
1761
+ Value *SizeEq0 = Builder.CreateICmpEQ (Size , ConstantInt::get (SizeTy, 0 ));
1762
+ Builder.CreateCondBr (SizeEq0, Exit, CmpGT);
1763
+
1764
+ EmitBlock (CmpGT);
1765
+ PHINode *DstPhi = Builder.CreatePHI (Dst->getType (), 2 );
1766
+ DstPhi->addIncoming (Dst, Entry);
1767
+ PHINode *SrcPhi = Builder.CreatePHI (Src->getType (), 2 );
1768
+ SrcPhi->addIncoming (Src, Entry);
1769
+ PHINode *SizePhi = Builder.CreatePHI (SizeTy, 2 );
1770
+ SizePhi->addIncoming (Size , Entry);
1771
+ CharUnits WCharAlign =
1772
+ getContext ().getTypeAlignInChars (getContext ().WCharTy );
1773
+ Value *DstCh = Builder.CreateAlignedLoad (WCharTy, DstPhi, WCharAlign);
1774
+ Value *SrcCh = Builder.CreateAlignedLoad (WCharTy, SrcPhi, WCharAlign);
1775
+ Value *DstGtSrc = Builder.CreateICmpUGT (DstCh, SrcCh);
1776
+ Builder.CreateCondBr (DstGtSrc, Exit, CmpLT);
1777
+
1778
+ EmitBlock (CmpLT);
1779
+ Value *DstLtSrc = Builder.CreateICmpULT (DstCh, SrcCh);
1780
+ Builder.CreateCondBr (DstLtSrc, Exit, Next);
1781
+
1782
+ EmitBlock (Next);
1783
+ Value *NextDst = Builder.CreateConstInBoundsGEP1_32 (WCharTy, DstPhi, 1 );
1784
+ Value *NextSrc = Builder.CreateConstInBoundsGEP1_32 (WCharTy, SrcPhi, 1 );
1785
+ Value *NextSize = Builder.CreateSub (SizePhi, ConstantInt::get (SizeTy, 1 ));
1786
+ Value *NextSizeEq0 =
1787
+ Builder.CreateICmpEQ (NextSize, ConstantInt::get (SizeTy, 0 ));
1788
+ Builder.CreateCondBr (NextSizeEq0, Exit, CmpGT);
1789
+ DstPhi->addIncoming (NextDst, Next);
1790
+ SrcPhi->addIncoming (NextSrc, Next);
1791
+ SizePhi->addIncoming (NextSize, Next);
1792
+
1793
+ EmitBlock (Exit);
1794
+ PHINode *Ret = Builder.CreatePHI (IntTy, 4 );
1795
+ Ret->addIncoming (ConstantInt::get (IntTy, 0 ), Entry);
1796
+ Ret->addIncoming (ConstantInt::get (IntTy, 1 ), CmpGT);
1797
+ Ret->addIncoming (ConstantInt::get (IntTy, -1 ), CmpLT);
1798
+ Ret->addIncoming (ConstantInt::get (IntTy, 0 ), Next);
1799
+ return RValue::get (Ret);
1800
+ }
1744
1801
case Builtin::BI__builtin_dwarf_cfa: {
1745
1802
// The offset in bytes from the first argument to the CFA.
1746
1803
//
0 commit comments