@@ -2339,68 +2339,88 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC,
23392339 assert (Call->getNumArgs () == 2 );
23402340
23412341 QualType Arg0Type = Call->getArg (0 )->getType ();
2342+ QualType Arg1Type = Call->getArg (1 )->getType ();
23422343
2343- // TODO: Support floating-point types.
2344- if (!(Arg0Type->isIntegerType () ||
2345- (Arg0Type->isVectorType () &&
2346- Arg0Type->castAs <VectorType>()->getElementType ()->isIntegerType ())))
2347- return false ;
2348-
2349- if (!Arg0Type->isVectorType ()) {
2350- assert (!Call->getArg (1 )->getType ()->isVectorType ());
2351- APSInt RHS = popToAPSInt (
2352- S.Stk , *S.getContext ().classify (Call->getArg (1 )->getType ()));
2353- APSInt LHS = popToAPSInt (
2354- S.Stk , *S.getContext ().classify (Call->getArg (0 )->getType ()));
2355- APInt Result;
2344+ if (Arg0Type->isIntegerType ()) {
2345+ assert (Arg1Type->isIntegerType ());
2346+ APSInt RHS = popToAPSInt (S.Stk , *S.getContext ().classify (Arg1Type));
2347+ APSInt LHS = popToAPSInt (S.Stk , *S.getContext ().classify (Arg0Type));
2348+ APSInt Result;
23562349 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
23572350 Result = std::max (LHS, RHS);
23582351 } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
23592352 Result = std::min (LHS, RHS);
23602353 } else {
23612354 llvm_unreachable (" Wrong builtin ID" );
23622355 }
2356+ pushInteger (S, Result, Call->getType ());
2357+ return true ;
2358+ }
23632359
2364- pushInteger (S, APSInt (Result, !LHS.isSigned ()), Call->getType ());
2360+ if (Arg0Type->isRealFloatingType ()) {
2361+ assert (Arg1Type->isRealFloatingType ());
2362+ APFloat RHS = S.Stk .pop <Floating>().getAPFloat ();
2363+ APFloat LHS = S.Stk .pop <Floating>().getAPFloat ();
2364+ Floating Result = S.allocFloat (RHS.getSemantics ());
2365+ if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2366+ Result.copy (maxnum (LHS, RHS));
2367+ } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2368+ Result.copy (minnum (LHS, RHS));
2369+ } else {
2370+ llvm_unreachable (" Wrong builtin ID" );
2371+ }
2372+ S.Stk .push <Floating>(Result);
23652373 return true ;
23662374 }
23672375
23682376 // Vector case.
2369- assert (Call->getArg (0 )->getType ()->isVectorType () &&
2370- Call->getArg (1 )->getType ()->isVectorType ());
2371- const auto *VT = Call->getArg (0 )->getType ()->castAs <VectorType>();
2372- assert (VT->getElementType () ==
2373- Call->getArg (1 )->getType ()->castAs <VectorType>()->getElementType ());
2374- assert (VT->getNumElements () ==
2375- Call->getArg (1 )->getType ()->castAs <VectorType>()->getNumElements ());
2376- assert (VT->getElementType ()->isIntegralOrEnumerationType ());
2377+ assert (Arg0Type->isVectorType () && Arg1Type->isVectorType ());
2378+
2379+ const auto *VT = Arg0Type->castAs <VectorType>();
2380+ QualType ElemType = VT->getElementType ();
2381+ unsigned NumElems = VT->getNumElements ();
2382+
2383+ assert (ElemType == Arg1Type->castAs <VectorType>()->getElementType ());
2384+ assert (NumElems == Arg1Type->castAs <VectorType>()->getNumElements ());
2385+ assert (ElemType->isIntegerType () || ElemType->isRealFloatingType ());
23772386
23782387 const Pointer &RHS = S.Stk .pop <Pointer>();
23792388 const Pointer &LHS = S.Stk .pop <Pointer>();
23802389 const Pointer &Dst = S.Stk .peek <Pointer>();
2381- PrimType ElemT = *S.getContext ().classify (VT->getElementType ());
2382- unsigned NumElems = VT->getNumElements ();
2390+ PrimType ElemT = *S.getContext ().classify (ElemType);
23832391 for (unsigned I = 0 ; I != NumElems; ++I) {
2384- APSInt Elem1;
2385- APSInt Elem2;
2386- INT_TYPE_SWITCH_NO_BOOL (ElemT, {
2387- Elem1 = LHS.elem <T>(I).toAPSInt ();
2388- Elem2 = RHS.elem <T>(I).toAPSInt ();
2389- });
2392+ if (ElemType->isIntegerType ()) {
2393+ APSInt LHSInt;
2394+ APSInt RHSInt;
2395+ INT_TYPE_SWITCH_NO_BOOL (ElemT, {
2396+ LHSInt = LHS.elem <T>(I).toAPSInt ();
2397+ RHSInt = RHS.elem <T>(I).toAPSInt ();
2398+ });
23902399
2391- APSInt Result;
2392- if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2393- Result = APSInt (std::max (Elem1, Elem2),
2394- Call->getType ()->isUnsignedIntegerOrEnumerationType ());
2395- } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2396- Result = APSInt (std::min (Elem1, Elem2),
2397- Call->getType ()->isUnsignedIntegerOrEnumerationType ());
2400+ APSInt Result;
2401+ if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2402+ Result = std::max (LHSInt, RHSInt);
2403+ } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2404+ Result = std::min (LHSInt, RHSInt);
2405+ } else {
2406+ llvm_unreachable (" Wrong builtin ID" );
2407+ }
2408+
2409+ INT_TYPE_SWITCH_NO_BOOL (ElemT,
2410+ { Dst.elem <T>(I) = static_cast <T>(Result); });
23982411 } else {
2399- llvm_unreachable (" Wrong builtin ID" );
2412+ APFloat RHSFloat = RHS.elem <Floating>(I).getAPFloat ();
2413+ APFloat LHSFloat = LHS.elem <Floating>(I).getAPFloat ();
2414+ Floating Result = S.allocFloat (RHSFloat.getSemantics ());
2415+ if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2416+ Result.copy (maxnum (LHSFloat, RHSFloat));
2417+ } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2418+ Result.copy (minnum (LHSFloat, RHSFloat));
2419+ } else {
2420+ llvm_unreachable (" Wrong builtin ID" );
2421+ }
2422+ Dst.elem <Floating>(I) = Result;
24002423 }
2401-
2402- INT_TYPE_SWITCH_NO_BOOL (ElemT,
2403- { Dst.elem <T>(I) = static_cast <T>(Result); });
24042424 }
24052425 Dst.initializeAllElements ();
24062426
0 commit comments