Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/lib/AST/ByteCode/Integral.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ template <unsigned Bits, bool Signed> class Integral final {
template <typename T> static bool CheckMulUB(T A, T B, T &R) {
if constexpr (std::is_signed_v<T>) {
return llvm::MulOverflow<T>(A, B, R);
} else if constexpr (sizeof(T) < sizeof(int)) {
// Silly integer promotion rules will convert both A and B to int,
// even it T is unsigned. Prevent that by manually casting to uint first.
R = static_cast<T>(static_cast<unsigned>(A) * static_cast<unsigned>(B));
return false;
} else {
R = A * B;
return false;
Expand Down
48 changes: 44 additions & 4 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2518,9 +2518,9 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
return true;
}

static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
const CallExpr *Call,
unsigned BuiltinID) {
static bool interp__builtin_elementwise_int_binop(InterpState &S, CodePtr OpPC,
const CallExpr *Call,
unsigned BuiltinID) {
assert(Call->getNumArgs() == 2);

// Single integer case.
Expand Down Expand Up @@ -2557,6 +2557,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
const Pointer &LHS = S.Stk.pop<Pointer>();
const Pointer &Dst = S.Stk.peek<Pointer>();
PrimType ElemT = *S.getContext().classify(VT->getElementType());
bool DestUnsigned =
VT->getElementType()->isUnsignedIntegerOrEnumerationType();
unsigned NumElems = VT->getNumElements();
for (unsigned I = 0; I != NumElems; ++I) {
APSInt Elem1;
Expand Down Expand Up @@ -2590,6 +2592,34 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
Result = APSInt(llvm::APIntOps::mulhs(Elem1, Elem2),
/*isUnsigned=*/false);
break;
case clang::X86::BI__builtin_ia32_psllv2di:
case clang::X86::BI__builtin_ia32_psllv4di:
case clang::X86::BI__builtin_ia32_psllv4si:
case clang::X86::BI__builtin_ia32_psllv8si:
if (Elem2.uge(Elem2.getBitWidth())) {
Result = APSInt(APInt::getZero(Elem2.getBitWidth()), DestUnsigned);
break;
}
Result = APSInt(Elem1.shl(Elem2.getZExtValue()), DestUnsigned);
break;
case clang::X86::BI__builtin_ia32_psrav4si:
case clang::X86::BI__builtin_ia32_psrav8si:
if (Elem2.uge(Elem2.getBitWidth())) {
Result = APSInt(Elem1.ashr(Elem2.getBitWidth() - 1), DestUnsigned);
break;
}
Result = APSInt(Elem1.ashr(Elem2.getZExtValue()), DestUnsigned);
break;
case clang::X86::BI__builtin_ia32_psrlv2di:
case clang::X86::BI__builtin_ia32_psrlv4di:
case clang::X86::BI__builtin_ia32_psrlv4si:
case clang::X86::BI__builtin_ia32_psrlv8si:
if (Elem2.uge(Elem2.getBitWidth())) {
Result = APSInt(APInt::getZero(Elem2.getBitWidth()), DestUnsigned);
break;
}
Result = APSInt(Elem1.lshr(Elem2.getZExtValue()), DestUnsigned);
break;
default:
llvm_unreachable("Wrong builtin ID");
}
Expand Down Expand Up @@ -3236,7 +3266,17 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case clang::X86::BI__builtin_ia32_pmulhw128:
case clang::X86::BI__builtin_ia32_pmulhw256:
case clang::X86::BI__builtin_ia32_pmulhw512:
return interp__builtin_elementwise_sat(S, OpPC, Call, BuiltinID);
case clang::X86::BI__builtin_ia32_psllv2di:
case clang::X86::BI__builtin_ia32_psllv4di:
case clang::X86::BI__builtin_ia32_psllv4si:
case clang::X86::BI__builtin_ia32_psllv8si:
case clang::X86::BI__builtin_ia32_psrav4si:
case clang::X86::BI__builtin_ia32_psrav8si:
case clang::X86::BI__builtin_ia32_psrlv2di:
case clang::X86::BI__builtin_ia32_psrlv4di:
case clang::X86::BI__builtin_ia32_psrlv4si:
case clang::X86::BI__builtin_ia32_psrlv8si:
return interp__builtin_elementwise_int_binop(S, OpPC, Call, BuiltinID);

case Builtin::BI__builtin_elementwise_max:
case Builtin::BI__builtin_elementwise_min:
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CodeGen/X86/avx2-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=i386-apple-darwin -target-feature +avx2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,X86
// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=i386-apple-darwin -target-feature +avx2 -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,X86

// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx2 -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X64
// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx2 -fno-signed-char -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X64
// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=i386-apple-darwin -target-feature +avx2 -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X86
// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=i386-apple-darwin -target-feature +avx2 -fno-signed-char -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X86
// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx2 -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X64
// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx2 -fno-signed-char -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X64
// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=i386-apple-darwin -target-feature +avx2 -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X86
// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=i386-apple-darwin -target-feature +avx2 -fno-signed-char -emit-llvm -o - -Wall -Werror -fexperimental-new-constant-interpreter | FileCheck %s --check-prefixes=CHECK,X86

#include <immintrin.h>
#include "builtin_test_helpers.h"
Expand Down