@@ -3101,13 +3101,46 @@ static bool interp__builtin_vec_set(InterpState &S, CodePtr OpPC,
31013101 return true ;
31023102}
31033103
3104+ static bool evalICmpImm (const uint8_t imm, const llvm::APSInt &A,
3105+ const llvm::APSInt &B, bool IsUnsigned) {
3106+ switch (imm & 0x7 ) {
3107+ case 0x00 :
3108+ return (A == B);
3109+ break ;
3110+ case 0x01 :
3111+ return IsUnsigned ? A.ult (B) : A.slt (B);
3112+ break ;
3113+ case 0x02 :
3114+ return IsUnsigned ? A.ule (B) : A.sle (B);
3115+ break ;
3116+ case 0x03 :
3117+ return false ;
3118+ break ;
3119+ case 0x04 :
3120+ return (A != B);
3121+ break ;
3122+ case 0x05 :
3123+ return IsUnsigned ? A.ugt (B) : A.sgt (B);
3124+ break ;
3125+ case 0x06 :
3126+ return IsUnsigned ? A.uge (B) : A.sge (B);
3127+ break ;
3128+ case 0x07 :
3129+ return true ;
3130+ break ;
3131+ default :
3132+ llvm_unreachable (" Invalid Op" );
3133+ }
3134+ }
3135+
31043136static bool interp__builtin_cmp_mask (InterpState &S, CodePtr OpPC,
31053137 const CallExpr *Call, unsigned ID,
31063138 bool IsUnsigned) {
31073139 assert (Call->getNumArgs () == 4 );
31083140
31093141 APSInt Mask = popToAPSInt (S, Call->getArg (3 ));
31103142 APSInt Opcode = popToAPSInt (S, Call->getArg (2 ));
3143+ unsigned CmpOp = static_cast <unsigned >(Opcode.getZExtValue ());
31113144 const Pointer &RHS = S.Stk .pop <Pointer>();
31123145 const Pointer &LHS = S.Stk .pop <Pointer>();
31133146
@@ -3117,42 +3150,15 @@ static bool interp__builtin_cmp_mask(InterpState &S, CodePtr OpPC,
31173150 unsigned VectorLen = LHS.getNumElems ();
31183151 PrimType ElemT = LHS.getFieldDesc ()->getPrimType ();
31193152
3120- for (unsigned ElemNum = 0 ; ElemNum < VectorLen; ++ElemNum) {
3121- INT_TYPE_SWITCH_NO_BOOL (ElemT, {
3122- const APSInt &A = LHS.elem <T>(ElemNum).toAPSInt ();
3123- const APSInt &B = RHS.elem <T>(ElemNum).toAPSInt ();
3124- bool Result = false ;
3125- switch (Opcode.getExtValue () & 0x7 ) {
3126- case 0x00 : // _MM_CMPINT_EQ
3127- Result = (A == B);
3128- break ;
3129- case 0x01 : // _MM_CMPINT_LT
3130- Result = IsUnsigned ? A.ult (B) : A.slt (B);
3131- break ;
3132- case 0x02 : // _MM_CMPINT_LE
3133- Result = IsUnsigned ? A.ule (B) : A.sle (B);
3134- break ;
3135- case 0x03 : // _MM_CMPINT_FALSE
3136- Result = false ;
3137- break ;
3138- case 0x04 : // _MM_CMPINT_NE
3139- Result = (A != B);
3140- break ;
3141- case 0x05 : // _MM_CMPINT_NLT (>=)
3142- Result = IsUnsigned ? A.uge (B) : A.sge (B);
3143- break ;
3144- case 0x06 : // _MM_CMPINT_NLE (>)
3145- Result = IsUnsigned ? A.ugt (B) : A.sgt (B);
3146- break ;
3147- case 0x07 : // _MM_CMPINT_TRUE
3148- Result = true ;
3149- break ;
3150- }
3151-
3152- RetMask.setBitVal (ElemNum, Mask[ElemNum] && Result);
3153- });
3154- }
3155-
3153+ for (unsigned ElemNum = 0 ; ElemNum < VectorLen; ++ElemNum) {
3154+ INT_TYPE_SWITCH_NO_BOOL (ElemT, {
3155+ RetMask.setBitVal (ElemNum,
3156+ Mask[ElemNum] &&
3157+ evalICmpImm (CmpOp, LHS.elem <T>(ElemNum).toAPSInt (),
3158+ RHS.elem <T>(ElemNum).toAPSInt (),
3159+ IsUnsigned));
3160+ });
3161+ }
31563162 pushInteger (S, RetMask, Call->getType ());
31573163 return true ;
31583164}
0 commit comments