[llvm-commits] DIV -> U/S/FDiv Patch For Review

Chris Lattner clattner at apple.com
Tue Oct 24 21:40:04 PDT 2006


>
>> It would be more clear to return 0 here explicitly and mention in the
>> method comment that this returns null if no upgrading is needed.
>
> Except that's not quite the case. The function can return 0 but alter
> the OpCode argument.  I'll fix the comment to explain in more detail.

Great, thx.

>> *** This is flat out incorrect.  It should have separate
>> execute*DivInst functions that do the operation not based on the  
>> type.
>> This would misinterpret 'udiv int -4, 2' for example. This must be
>> fixed before you checkin.
>>
> Another casualty of thinking the operand types had to match the
> instruction type. I've created the three functions. The SDiv case now
> looks like:
>
> static GenericValue executeSDivInst(GenericValue Src1, GenericValue
> Src2,
>                                    const Type *Ty) {
*snip*

Looks good.

>> *** The CBE has the same problem.  You need to force the operands to
>> the right sign in the C output so that the C compiler will generate
>> the appropriately signed operation.  This must be fixed before you
>> checkin.
>
> Yes. Done. I added a writeOperandWithCast(Value*, unsigned opcode)
> method to the CWriter. It writes the operand with the correct cast  
> based
> on the opcode the value is used with. I call this instead of
> writeOperand(Value*) to write the operands for these binary operators
> (just before and after the switch statement you quoted above).

Sounds good.  Make sure that the result also ends up as the right  
type though.

>> You properly sign/zero extend the values here, but then proceed to do
>> the wrong division.  For example, this will do signed division for
>> 'udiv int -2, 2'.  What does the -constfold pass produce for:
>>
>>
>> int %test() { %X = udiv int -2, 2 ret int %X }
>>
>>
>> I bet it is folded to -1, which is incorrect.
>
> There's no -constfold pass on opt, but I ran it through gccas and yes,
> it does produce -1. I fixed it by changing:

Sorry, -constprop.

> BuiltinType R =
>>  (BuiltinType)V1->getSExtValue() / (BuiltinType)V2->getSExtValue();
>
> to:
>
> BuiltinType R = (BuiltinType)(V1->getSExtValue() / V2->getSExtValue 
> ());
>
> That produced the value of 2147483647 ((MAX_UINT-1)/2) for your test
> case which I think is correct.  Please confirm.

Sounds right.  getSExtValue returns a signed type, forcing a signed  
operation.  You do the same for udiv, right?



>>  Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) {
>>
>>
>> *** This would be an excellent place to assert that the arguments are
>> integer or fp (or vectors of) as appropriate.
>
> All of these cases call ConstantExpr::get(Opcode, C1, C2). That  
> function
> provides copious asserts. I didn't think it was reasonable to double
> them up, especially since the asserts in ConstantExpr::get are ifdef'd
> for debug only. I took that to mean that they were performance  
> sensitive
> for a release+asserts build.  Let me know if that's not the case (i.e.
> if I should remove the #ifndef DEBUG code in ConstantExpr::get).
>
> I looked at ConstantExpr::get and tightened up the asserts there.  
> It was
> allowing FP for UDiv and SDiv and integer for FDiv. Now it doesn't.

Sounds good!

-Chris




More information about the llvm-commits mailing list