Skip to content

Commit 769bd0e

Browse files
committed
fix popcount/bitreverse
1 parent 30b30fd commit 769bd0e

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,11 +2828,28 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
28282828
break;
28292829
case Builtin::BI__builtin_elementwise_popcount:
28302830
case Builtin::BI__builtin_elementwise_bitreverse: {
2831-
if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2831+
if (checkArgCount(TheCall, 1))
28322832
return ExprError();
28332833

2834-
const Expr *Arg = TheCall->getArg(0);
2834+
Expr *Arg = TheCall->getArg(0);
28352835
QualType ArgTy = Arg->getType();
2836+
2837+
// If the argument is a promotable integer type, do not perform the usual
2838+
// conversions - we must keep the operation at the correct bitwidth.
2839+
if (Context.isPromotableIntegerType(ArgTy)) {
2840+
// Convert the argument to an r-value - avoid the usual conversions.
2841+
ExprResult ResLHS = DefaultFunctionArrayLvalueConversion(Arg);
2842+
if (ResLHS.isInvalid())
2843+
return ExprError();
2844+
Arg = ResLHS.get();
2845+
TheCall->setArg(0, Arg);
2846+
TheCall->setType(Arg->getType());
2847+
break;
2848+
}
2849+
2850+
if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2851+
return ExprError();
2852+
28362853
QualType EltTy = ArgTy;
28372854

28382855
if (auto *VecTy = EltTy->getAs<VectorType>())

clang/test/CodeGen/builtins-elementwise-math.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ void test_builtin_elementwise_min(float f1, float f2, double d1, double d2,
512512

513513
void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2,
514514
long long int i1, long long int i2, short si,
515-
_BitInt(31) bi1, _BitInt(31) bi2) {
515+
_BitInt(31) bi1, _BitInt(31) bi2,
516+
char ci) {
516517

517518

518519
// CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8
@@ -541,10 +542,24 @@ void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2,
541542
b = __builtin_elementwise_bitreverse(-10);
542543

543544
// CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2
544-
// CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32
545-
// CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.bitreverse.i32(i32 [[SI_EXT]])
546-
// CHECK-NEXT: = trunc i32 [[RES]] to i16
545+
// CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.bitreverse.i16(i16 [[SI]])
547546
si = __builtin_elementwise_bitreverse(si);
547+
548+
// CHECK: store i16 28671, ptr %si.addr, align 2
549+
si = __builtin_elementwise_bitreverse((short)-10);
550+
551+
// CHECK: store i16 28671, ptr %si.addr, align 2
552+
si = __builtin_elementwise_bitreverse((unsigned short)-10);
553+
554+
// CHECK: [[CI:%.+]] = load i8, ptr %ci.addr, align 1
555+
// CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.bitreverse.i8(i8 [[CI]])
556+
ci = __builtin_elementwise_bitreverse(ci);
557+
558+
// CHECK: store i8 111, ptr %ci.addr, align 1
559+
ci = __builtin_elementwise_bitreverse((unsigned char)-10);
560+
561+
// CHECK: store i8 111, ptr %ci.addr, align 1
562+
ci = __builtin_elementwise_bitreverse((char)-10);
548563
}
549564

550565
void test_builtin_elementwise_ceil(float f1, float f2, double d1, double d2,
@@ -762,7 +777,8 @@ void test_builtin_elementwise_log2(float f1, float f2, double d1, double d2,
762777

763778
void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1,
764779
long long int i2, short si,
765-
_BitInt(31) bi1, _BitInt(31) bi2) {
780+
_BitInt(31) bi1, _BitInt(31) bi2,
781+
char ci) {
766782
// CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8
767783
// CHECK-NEXT: call i64 @llvm.ctpop.i64(i64 [[I1]])
768784
i2 = __builtin_elementwise_popcount(i1);
@@ -789,10 +805,24 @@ void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1,
789805
b = __builtin_elementwise_popcount(-10);
790806

791807
// CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2
792-
// CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32
793-
// CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.ctpop.i32(i32 [[SI_EXT]])
794-
// CHECK-NEXT: = trunc i32 [[RES]] to i16
808+
// CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.ctpop.i16(i16 [[SI]])
795809
si = __builtin_elementwise_popcount(si);
810+
811+
// CHECK: store i16 3, ptr %si.addr, align 2
812+
si = __builtin_elementwise_popcount((unsigned short)32771);
813+
814+
// CHECK: store i16 3, ptr %si.addr, align 2
815+
si = __builtin_elementwise_popcount((short)32771);
816+
817+
// CHECK: [[CI:%.+]] = load i8, ptr %ci.addr, align 1
818+
// CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.ctpop.i8(i8 [[CI]])
819+
ci = __builtin_elementwise_popcount(ci);
820+
821+
// CHECK: store i8 2, ptr %ci.addr, align 1
822+
ci = __builtin_elementwise_popcount((unsigned char)192);
823+
824+
// CHECK: store i8 2, ptr %ci.addr, align 1
825+
ci = __builtin_elementwise_popcount((char)192);
796826
}
797827

798828
void test_builtin_elementwise_fmod(float f1, float f2, double d1, double d2,

0 commit comments

Comments
 (0)