This is an archive of the discontinued LLVM Phabricator instance.

[Sema] Support lax conversions for compound assignments
ClosedPublic

Authored by bruno on Sep 12 2016, 2:05 PM.

Details

Summary

Support lax conversions on compound assignment expressions like:

typedef __attribute__((vector_size(8))) double float64x1_t;
typedef __attribute__((vector_size(16))) double float64x2_t;
float64x1_t vget_low_f64(float64x2_t __p0);

double c = 3.0;
float64x2_t v = {0.0, 1.0};
c += vget_low_f64(v);

This restores one more valid behavior pre r266366, and is a incremental
follow up from work committed in r274646.

While here, make the check more strict, add FIXMEs, clean up variable
names to match what they can actually be and update testcase to reflect
that. We now reject:

typedef float float2 __attribute__ ((vector_size (8)));
double d;
f2 += d;

which doesn't fit as a direct bitcast anyway.

Diff Detail

Event Timeline

bruno updated this revision to Diff 71052.Sep 12 2016, 2:05 PM
bruno retitled this revision from to [Sema] Support lax conversions for compound assignments.
bruno updated this object.
bruno added a reviewer: rnk.
bruno added subscribers: cfe-commits, ahatanak.
ahatanak added inline comments.Sep 19 2016, 10:41 AM
lib/Sema/SemaExpr.cpp
8090

My understanding is that, when we have a compound assign like "LHS += RHS", this function (CheckVectorOperands) is supposed to return the result type (LHS + RHS). However, it is returning different types for "<1 x T> += T" and "T += <1 x T>" (the former returns <1 x T> and the latter returns T). Would CheckAssignmentOperands reject the compound statement if you returned the vector type here?

Also, are you planning to allow the same kind of conversions done above for non-compound assignment statements (e.g., <4 x short> += <2 x int>) in the future?

bruno marked an inline comment as done.Sep 19 2016, 12:58 PM
bruno added inline comments.
lib/Sema/SemaExpr.cpp
8090
  1. CheckAssignmentOperands doesn't reject the compound statement if we return the vector type instead, because it already supports vector to scalar cast idiom. It makes more sense to return a vector indeed, gonna change that.
  1. It would be nice to catch up with GCC with the idioms supported for regular (non-ext) vectors (like splatting scalar operands to vectors in a arith binops), and those, AFAIK, don't include support for truncation as in the example you suggested. I guess this is supported with ext-vectors, but I don't see any reason to support it for "regular" vectors.
bruno updated this revision to Diff 71869.Sep 19 2016, 12:59 PM
bruno marked an inline comment as done.

Update after Akira's comment

bruno updated this revision to Diff 71870.Sep 19 2016, 1:01 PM

Update again (now with the right patch) after Akira's comment

Thanks Bruno. I have a couple more questions.

lib/Sema/SemaExpr.cpp
8090

Sorry I wasn't clear, but I was asking whether you were planning to allow the following conversions for compound statements.

typedef short s4 __attribute__ ((vector_size(8)));
typedef int i2 __attribute__ ((vector_size(8)));
s4 a;
i2 b;
a = a + b; // clang accepts this.
a += b; // currently clang rejects this.

Also, I feel clang is inconsistent in warning about incompatible types. In the following example, it issues a warning for the first line, but is silent about the second line:

a = b + a; // incompatible vector types warning
a = a + b; // no warning

I don't think we have to fix everything in this patch, but just wanted to know what your thoughts were.

bruno added inline comments.Sep 23 2016, 2:50 PM
lib/Sema/SemaExpr.cpp
8090

You're right, the diagnostics are bad here, this patch adds some FIXMEs so we can later work on it. A PR would be nice though (we have an internal track for that as well, see rdar://problem/28067874).

Given your example:

a = a + b; // clang accepts this. 
a += b; // currently clang rejects this.

IMO, clang should reject a = a + b too if not in OpenCL mode, which means whenever (a) a and b have same size but different num elt and (b) a and b are generic vectors (non ext-vectors). However, It looks like we have tests that rely on this behavior, we should probably find out why first and clean it up.

I also think we should support splatting when one of the operands is a scalar and the other a non ext-vector (as of now we currently only do it for OpenCL). This is basically what GCC supports https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html.

@rnk, do you have any concerns about this patch?

rnk accepted this revision.Sep 30 2016, 9:52 AM
rnk edited edge metadata.

lgtm

lib/Sema/SemaExpr.cpp
8084

typo on biscast

8090

I agree. I think the way forward is to:

  • Allow conversions between <1 x T> and scalar T without enabling lax vector conversions. This seems pretty unobjectionable.
  • Disable lax vector conversions by default, and evaluate whether they can be completely removed.
This revision is now accepted and ready to land.Sep 30 2016, 9:52 AM
bruno closed this revision.Sep 30 2016, 3:29 PM

Thanks Reid & Akira,

Committed r282968