llvm-project/clang/test/CodeGen/arm-mve-intrinsics/scalar-shifts.c

257 lines
10 KiB
C

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
// REQUIRES: aarch64-registered-target || arm-registered-target
#include <arm_mve.h>
// CHECK-LABEL: @test_asrl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.asrl(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]])
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
int64_t test_asrl(int64_t value, int32_t shift)
{
return asrl(value, shift);
}
// CHECK-LABEL: @test_lsll(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.lsll(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]])
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
uint64_t test_lsll(uint64_t value, int32_t shift)
{
return lsll(value, shift);
}
// CHECK-LABEL: @test_sqrshr(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.mve.sqrshr(i32 [[VALUE:%.*]], i32 [[SHIFT:%.*]])
// CHECK-NEXT: ret i32 [[TMP0]]
//
int32_t test_sqrshr(int32_t value, int32_t shift)
{
return sqrshr(value, shift);
}
// CHECK-LABEL: @test_sqrshrl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.sqrshrl(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 64)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
int64_t test_sqrshrl(int64_t value, int32_t shift)
{
return sqrshrl(value, shift);
}
// CHECK-LABEL: @test_sqrshrl_sat48(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.sqrshrl(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 48)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
int64_t test_sqrshrl_sat48(int64_t value, int32_t shift)
{
return sqrshrl_sat48(value, shift);
}
// CHECK-LABEL: @test_sqshl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.mve.sqshl(i32 [[VALUE:%.*]], i32 2)
// CHECK-NEXT: ret i32 [[TMP0]]
//
int32_t test_sqshl(int32_t value)
{
return sqshl(value, 2);
}
// CHECK-LABEL: @test_sqshll(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.sqshll(i32 [[TMP2]], i32 [[TMP1]], i32 17)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
int64_t test_sqshll(int64_t value)
{
return sqshll(value, 17);
}
// CHECK-LABEL: @test_srshr(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.mve.srshr(i32 [[VALUE:%.*]], i32 6)
// CHECK-NEXT: ret i32 [[TMP0]]
//
int32_t test_srshr(int32_t value)
{
return srshr(value, 6);
}
// CHECK-LABEL: @test_srshrl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.srshrl(i32 [[TMP2]], i32 [[TMP1]], i32 26)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
int64_t test_srshrl(int64_t value)
{
return srshrl(value, 26);
}
// CHECK-LABEL: @test_uqrshl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.mve.uqrshl(i32 [[VALUE:%.*]], i32 [[SHIFT:%.*]])
// CHECK-NEXT: ret i32 [[TMP0]]
//
uint32_t test_uqrshl(uint32_t value, int32_t shift)
{
return uqrshl(value, shift);
}
// CHECK-LABEL: @test_uqrshll(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.uqrshll(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 64)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
uint64_t test_uqrshll(uint64_t value, int32_t shift)
{
return uqrshll(value, shift);
}
// CHECK-LABEL: @test_uqrshll_sat48(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.uqrshll(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 48)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
uint64_t test_uqrshll_sat48(uint64_t value, int32_t shift)
{
return uqrshll_sat48(value, shift);
}
// CHECK-LABEL: @test_uqshl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.mve.uqshl(i32 [[VALUE:%.*]], i32 21)
// CHECK-NEXT: ret i32 [[TMP0]]
//
uint32_t test_uqshl(uint32_t value)
{
return uqshl(value, 21);
}
// CHECK-LABEL: @test_uqshll(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.uqshll(i32 [[TMP2]], i32 [[TMP1]], i32 16)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
uint64_t test_uqshll(uint64_t value)
{
return uqshll(value, 16);
}
// CHECK-LABEL: @test_urshr(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.mve.urshr(i32 [[VALUE:%.*]], i32 22)
// CHECK-NEXT: ret i32 [[TMP0]]
//
uint32_t test_urshr(uint32_t value)
{
return urshr(value, 22);
}
// CHECK-LABEL: @test_urshrl(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
// CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
// CHECK-NEXT: [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.urshrl(i32 [[TMP2]], i32 [[TMP1]], i32 6)
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
// CHECK-NEXT: [[TMP6:%.*]] = shl i64 [[TMP5]], 32
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
// CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
// CHECK-NEXT: [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
// CHECK-NEXT: ret i64 [[TMP9]]
//
uint64_t test_urshrl(uint64_t value)
{
return urshrl(value, 6);
}