Skip to content

C++: Handle Arm SVE in the IR #19845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ private predicate isDeeplyConstBelow(Type t) {
or
isDeeplyConst(t.(GNUVectorType).getBaseType())
or
isDeeplyConst(t.(ScalableVectorType).getBaseType())
or
Comment on lines 55 to +58
Copy link
Preview

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider grouping the vector-type const checks (GNUVectorType and ScalableVectorType) into a single reusable predicate to reduce duplication.

Suggested change
isDeeplyConst(t.(GNUVectorType).getBaseType())
or
isDeeplyConst(t.(ScalableVectorType).getBaseType())
or
isVectorType(t) and isDeeplyConst(t.getBaseType())
or

Copilot uses AI. Check for mistakes.

isDeeplyConst(t.(FunctionPointerIshType).getBaseType())
or
isDeeplyConst(t.(PointerWrapper).getTemplateArgument(0))
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/ir/internal/CppType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ private int getTypeSizeWorkaround(Type type) {
not arrayType.hasArraySize() and
result = getPointerSize()
)
or
// Scalable vectors are opaque and not of fixed size. Use 0 as a substitute.
type instanceof ScalableVectorType and
result = 0
)
)
}
Expand Down Expand Up @@ -136,6 +140,8 @@ private predicate isOpaqueType(Type type) {
type instanceof PointerToMemberType // PTMs are missing size info
or
type instanceof ScalableVectorCount
or
type instanceof ScalableVectorType
}

/**
Expand Down
150 changes: 98 additions & 52 deletions cpp/ql/test/library-tests/ir/ir/PrintAST.expected
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
#-----| Type = [LongType] unsigned long
#-----| getParameter(1): [Parameter] (unnamed parameter 1)
#-----| Type = [ScopedEnum] align_val_t
arm.cpp:
arm_neon.cpp:
# 6| [TopLevelFunction] uint8x8_t vadd_u8(uint8x8_t, uint8x8_t)
# 6| <params>:
# 6| getParameter(0): [Parameter] a
Expand All @@ -76,59 +76,105 @@ arm.cpp:
# 7| getRightOperand(): [VariableAccess] b
# 7| Type = [CTypedefType] uint8x8_t
# 7| ValueCategory = prvalue(load)
# 12| [TopLevelFunction] uint16x8_t __builtin_aarch64_uaddlv8qi_uuu(uint8x8_t, uint8x8_t)
# 10| [TopLevelFunction] uint16x8_t vaddl_u8(uint8x8_t, uint8x8_t)
# 10| <params>:
# 10| getParameter(0): [Parameter] a
# 10| Type = [CTypedefType] uint8x8_t
# 10| getParameter(1): [Parameter] b
# 10| Type = [CTypedefType] uint8x8_t
# 12| [TopLevelFunction] uint16x8_t arm_add(uint8x8_t, uint8x8_t*)
# 12| <params>:
# 12| getParameter(0): [Parameter] (unnamed parameter 0)
# 12| Type = [CTypedefType] uint8x8_t
# 12| getParameter(1): [Parameter] (unnamed parameter 1)
# 12| getParameter(0): [Parameter] a
# 12| Type = [CTypedefType] uint8x8_t
# 14| [TopLevelFunction] uint16x8_t vaddl_u8(uint8x8_t, uint8x8_t)
# 14| <params>:
# 14| getParameter(0): [Parameter] a
# 14| Type = [CTypedefType] uint8x8_t
# 14| getParameter(1): [Parameter] b
# 14| Type = [CTypedefType] uint8x8_t
# 14| getEntryPoint(): [BlockStmt] { ... }
# 15| getStmt(0): [ReturnStmt] return ...
# 15| getExpr(): [FunctionCall] call to __builtin_aarch64_uaddlv8qi_uuu
# 15| Type = [CTypedefType] uint16x8_t
# 15| ValueCategory = prvalue
# 15| getArgument(0): [VariableAccess] a
# 15| Type = [CTypedefType] uint8x8_t
# 15| ValueCategory = prvalue(load)
# 15| getArgument(1): [VariableAccess] b
# 15| Type = [CTypedefType] uint8x8_t
# 15| ValueCategory = prvalue(load)
# 18| [TopLevelFunction] uint16x8_t arm_add(uint8x8_t, uint8x8_t)
# 18| <params>:
# 18| getParameter(0): [Parameter] a
# 18| Type = [CTypedefType] uint8x8_t
# 18| getParameter(1): [Parameter] b
# 18| Type = [CTypedefType] uint8x8_t
# 18| getEntryPoint(): [BlockStmt] { ... }
# 19| getStmt(0): [DeclStmt] declaration
# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
# 19| Type = [CTypedefType] uint8x8_t
# 19| getVariable().getInitializer(): [Initializer] initializer for c
# 19| getExpr(): [FunctionCall] call to vadd_u8
# 19| Type = [CTypedefType] uint8x8_t
# 19| ValueCategory = prvalue
# 19| getArgument(0): [VariableAccess] a
# 19| Type = [CTypedefType] uint8x8_t
# 19| ValueCategory = prvalue(load)
# 19| getArgument(1): [VariableAccess] b
# 19| Type = [CTypedefType] uint8x8_t
# 19| ValueCategory = prvalue(load)
# 20| getStmt(1): [ReturnStmt] return ...
# 20| getExpr(): [FunctionCall] call to vaddl_u8
# 20| Type = [CTypedefType] uint16x8_t
# 20| ValueCategory = prvalue
# 20| getArgument(0): [VariableAccess] a
# 20| Type = [CTypedefType] uint8x8_t
# 20| ValueCategory = prvalue(load)
# 20| getArgument(1): [VariableAccess] c
# 20| Type = [CTypedefType] uint8x8_t
# 20| ValueCategory = prvalue(load)
# 12| getParameter(1): [Parameter] b
# 12| Type = [PointerType] uint8x8_t *
# 12| getEntryPoint(): [BlockStmt] { ... }
# 13| getStmt(0): [DeclStmt] declaration
# 13| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
# 13| Type = [CTypedefType] uint8x8_t
# 13| getVariable().getInitializer(): [Initializer] initializer for c
# 13| getExpr(): [FunctionCall] call to vadd_u8
# 13| Type = [CTypedefType] uint8x8_t
# 13| ValueCategory = prvalue
# 13| getArgument(0): [VariableAccess] a
# 13| Type = [CTypedefType] uint8x8_t
# 13| ValueCategory = prvalue(load)
# 13| getArgument(1): [PointerDereferenceExpr] * ...
# 13| Type = [CTypedefType] uint8x8_t
# 13| ValueCategory = prvalue(load)
# 13| getOperand(): [VariableAccess] b
# 13| Type = [PointerType] uint8x8_t *
# 13| ValueCategory = prvalue(load)
# 14| getStmt(1): [ReturnStmt] return ...
# 14| getExpr(): [FunctionCall] call to vaddl_u8
# 14| Type = [CTypedefType] uint16x8_t
# 14| ValueCategory = prvalue
# 14| getArgument(0): [VariableAccess] a
# 14| Type = [CTypedefType] uint8x8_t
# 14| ValueCategory = prvalue(load)
# 14| getArgument(1): [VariableAccess] c
# 14| Type = [CTypedefType] uint8x8_t
# 14| ValueCategory = prvalue(load)
# 20| [TopLevelFunction] mfloat8x8_t vreinterpret_mf8_s8(int8x8_t)
# 20| <params>:
# 20| getParameter(0): [Parameter] (unnamed parameter 0)
# 20| Type = [CTypedefType] int8x8_t
# 22| [TopLevelFunction] mfloat8x8_t arm_reinterpret(int8x8_t*)
# 22| <params>:
# 22| getParameter(0): [Parameter] a
# 22| Type = [PointerType] int8x8_t *
# 22| getEntryPoint(): [BlockStmt] { ... }
# 23| getStmt(0): [ReturnStmt] return ...
# 23| getExpr(): [FunctionCall] call to vreinterpret_mf8_s8
# 23| Type = [CTypedefType] mfloat8x8_t
# 23| ValueCategory = prvalue
# 23| getArgument(0): [PointerDereferenceExpr] * ...
# 23| Type = [CTypedefType] int8x8_t
# 23| ValueCategory = prvalue(load)
# 23| getOperand(): [VariableAccess] a
# 23| Type = [PointerType] int8x8_t *
# 23| ValueCategory = prvalue(load)
arm_sve.cpp:
# 6| [TopLevelFunction] svuint8x2_t svsel_u8_x2(svcount_t, svuint8x2_t, svuint8x2_t)
# 6| <params>:
# 6| getParameter(0): [Parameter] (unnamed parameter 0)
# 6| Type = [CTypedefType] svcount_t
# 6| getParameter(1): [Parameter] (unnamed parameter 1)
# 6| Type = [CTypedefType] svuint8x2_t
# 6| getParameter(2): [Parameter] (unnamed parameter 2)
# 6| Type = [CTypedefType] svuint8x2_t
# 8| [TopLevelFunction] svuint8x2_t arm_sel(svcount_t, svuint8x2_t, svuint8x2_t*)
# 8| <params>:
# 8| getParameter(0): [Parameter] a
# 8| Type = [CTypedefType] svcount_t
# 8| getParameter(1): [Parameter] b
# 8| Type = [CTypedefType] svuint8x2_t
# 8| getParameter(2): [Parameter] c
# 8| Type = [PointerType] svuint8x2_t *
# 8| getEntryPoint(): [BlockStmt] { ... }
# 9| getStmt(0): [DeclStmt] declaration
# 9| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
# 9| Type = [CTypedefType] svuint8x2_t
# 9| getVariable().getInitializer(): [Initializer] initializer for d
# 9| getExpr(): [FunctionCall] call to svsel_u8_x2
# 9| Type = [CTypedefType] svuint8x2_t
# 9| ValueCategory = prvalue
# 9| getArgument(0): [VariableAccess] a
# 9| Type = [CTypedefType] svcount_t
# 9| ValueCategory = prvalue(load)
# 9| getArgument(1): [VariableAccess] b
# 9| Type = [CTypedefType] svuint8x2_t
# 9| ValueCategory = prvalue(load)
# 9| getArgument(2): [PointerDereferenceExpr] * ...
# 9| Type = [CTypedefType] svuint8x2_t
# 9| ValueCategory = prvalue(load)
# 9| getOperand(): [VariableAccess] c
# 9| Type = [PointerType] svuint8x2_t *
# 9| ValueCategory = prvalue(load)
# 10| getStmt(1): [ReturnStmt] return ...
# 10| getExpr(): [VariableAccess] d
# 10| Type = [CTypedefType] svuint8x2_t
# 10| ValueCategory = prvalue(load)
bad_asts.cpp:
# 5| [CopyAssignmentOperator] Bad::S& Bad::S::operator=(Bad::S const&)
# 5| <params>:
Expand Down
Loading
Loading