Skip to content

Commit 21769a2

Browse files
committed
[clang][bytecode] Support remaining add_sat like X86 builtins
Checking CI with the RUN lines. They won't be pushed though because of a signed integer overflow reported by ubsan that seems to happen on unsigned types.
1 parent acf9611 commit 21769a2

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

clang/lib/AST/ByteCode/Integral.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ template <unsigned Bits, bool Signed> class Integral final {
318318
template <typename T> static bool CheckMulUB(T A, T B, T &R) {
319319
if constexpr (std::is_signed_v<T>) {
320320
return llvm::MulOverflow<T>(A, B, R);
321+
} else if constexpr (sizeof(T) < sizeof(int)) {
322+
// Silly integer promotion rules will convert both A and B to int,
323+
// even it T is unsigned. Prevent that by manually casting to uint first.
324+
R = static_cast<T>(static_cast<unsigned>(A) * static_cast<unsigned>(B));
325+
return false;
321326
} else {
322327
R = A * B;
323328
return false;

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,6 +2557,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
25572557
const Pointer &LHS = S.Stk.pop<Pointer>();
25582558
const Pointer &Dst = S.Stk.peek<Pointer>();
25592559
PrimType ElemT = *S.getContext().classify(VT->getElementType());
2560+
bool DestUnsigned =
2561+
VT->getElementType()->isUnsignedIntegerOrEnumerationType();
25602562
unsigned NumElems = VT->getNumElements();
25612563
for (unsigned I = 0; I != NumElems; ++I) {
25622564
APSInt Elem1;
@@ -2590,6 +2592,34 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
25902592
Result = APSInt(llvm::APIntOps::mulhs(Elem1, Elem2),
25912593
/*isUnsigned=*/false);
25922594
break;
2595+
case clang::X86::BI__builtin_ia32_psllv2di:
2596+
case clang::X86::BI__builtin_ia32_psllv4di:
2597+
case clang::X86::BI__builtin_ia32_psllv4si:
2598+
case clang::X86::BI__builtin_ia32_psllv8si:
2599+
if (Elem2.uge(Elem2.getBitWidth())) {
2600+
Result = APSInt(APInt::getZero(Elem2.getBitWidth()), DestUnsigned);
2601+
break;
2602+
}
2603+
Result = APSInt(Elem1.shl(Elem2.getZExtValue()), DestUnsigned);
2604+
break;
2605+
case clang::X86::BI__builtin_ia32_psrav4si:
2606+
case clang::X86::BI__builtin_ia32_psrav8si:
2607+
if (Elem2.uge(Elem2.getBitWidth())) {
2608+
Result = APSInt(Elem1.ashr(Elem2.getBitWidth() - 1), DestUnsigned);
2609+
break;
2610+
}
2611+
Result = APSInt(Elem1.ashr(Elem2.getZExtValue()), DestUnsigned);
2612+
break;
2613+
case clang::X86::BI__builtin_ia32_psrlv2di:
2614+
case clang::X86::BI__builtin_ia32_psrlv4di:
2615+
case clang::X86::BI__builtin_ia32_psrlv4si:
2616+
case clang::X86::BI__builtin_ia32_psrlv8si:
2617+
if (Elem2.uge(Elem2.getBitWidth())) {
2618+
Result = APSInt(APInt::getZero(Elem2.getBitWidth()), DestUnsigned);
2619+
break;
2620+
}
2621+
Result = APSInt(Elem1.lshr(Elem2.getZExtValue()), DestUnsigned);
2622+
break;
25932623
default:
25942624
llvm_unreachable("Wrong builtin ID");
25952625
}
@@ -3236,6 +3266,16 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32363266
case clang::X86::BI__builtin_ia32_pmulhw128:
32373267
case clang::X86::BI__builtin_ia32_pmulhw256:
32383268
case clang::X86::BI__builtin_ia32_pmulhw512:
3269+
case clang::X86::BI__builtin_ia32_psllv2di:
3270+
case clang::X86::BI__builtin_ia32_psllv4di:
3271+
case clang::X86::BI__builtin_ia32_psllv4si:
3272+
case clang::X86::BI__builtin_ia32_psllv8si:
3273+
case clang::X86::BI__builtin_ia32_psrav4si:
3274+
case clang::X86::BI__builtin_ia32_psrav8si:
3275+
case clang::X86::BI__builtin_ia32_psrlv2di:
3276+
case clang::X86::BI__builtin_ia32_psrlv4di:
3277+
case clang::X86::BI__builtin_ia32_psrlv4si:
3278+
case clang::X86::BI__builtin_ia32_psrlv8si:
32393279
return interp__builtin_elementwise_sat(S, OpPC, Call, BuiltinID);
32403280

32413281
case Builtin::BI__builtin_elementwise_max:

clang/test/CodeGen/X86/avx2-builtins.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
// 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
88
// 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
99

10+
// 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
11+
// 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
12+
// 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
13+
// 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
14+
// 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
15+
// 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
16+
// 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
17+
// 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
1018

1119
#include <immintrin.h>
1220
#include "builtin_test_helpers.h"

0 commit comments

Comments
 (0)