1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 2 // RUN: %clang_cc1 -triple arm-unknown-unknown -O0 -std=c23 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-O0 3 // RUN: %clang_cc1 -triple arm-unknown-unknown -O1 -std=c23 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-O1 4 5 // Verify that the result from the intrinsic call is zero extended to avoid that 6 // we get a negative result from popcountg/ctzg/clzg. 7 8 // CHECK-O0-LABEL: define dso_local arm_aapcscc i32 @test_popcountg_ubi1( 9 // CHECK-O0-SAME: ) #[[ATTR0:[0-9]+]] { 10 // CHECK-O0-NEXT: entry: 11 // CHECK-O0-NEXT: [[A:%.*]] = alloca i8, align 1 12 // CHECK-O0-NEXT: store i8 1, ptr [[A]], align 1 13 // CHECK-O0-NEXT: [[TMP0:%.*]] = load i8, ptr [[A]], align 1 14 // CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1 15 // CHECK-O0-NEXT: [[TMP1:%.*]] = call i1 @llvm.ctpop.i1(i1 [[LOADEDV]]) 16 // CHECK-O0-NEXT: [[CAST:%.*]] = zext i1 [[TMP1]] to i32 17 // CHECK-O0-NEXT: ret i32 [[CAST]] 18 // 19 // CHECK-O1-LABEL: define dso_local arm_aapcscc noundef i32 @test_popcountg_ubi1( 20 // CHECK-O1-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] { 21 // CHECK-O1-NEXT: entry: 22 // CHECK-O1-NEXT: ret i32 1 23 // 24 int test_popcountg_ubi1() { 25 unsigned _BitInt(1) a = 1uwb; 26 return __builtin_popcountg(a); 27 } 28 29 // CHECK-O0-LABEL: define dso_local arm_aapcscc i32 @test_popcountg_ubi2( 30 // CHECK-O0-SAME: ) #[[ATTR0]] { 31 // CHECK-O0-NEXT: entry: 32 // CHECK-O0-NEXT: [[A:%.*]] = alloca i8, align 1 33 // CHECK-O0-NEXT: store i8 3, ptr [[A]], align 1 34 // CHECK-O0-NEXT: [[TMP0:%.*]] = load i8, ptr [[A]], align 1 35 // CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i2 36 // CHECK-O0-NEXT: [[TMP1:%.*]] = call i2 @llvm.ctpop.i2(i2 [[LOADEDV]]) 37 // CHECK-O0-NEXT: [[CAST:%.*]] = zext i2 [[TMP1]] to i32 38 // CHECK-O0-NEXT: ret i32 [[CAST]] 39 // 40 // CHECK-O1-LABEL: define dso_local arm_aapcscc noundef i32 @test_popcountg_ubi2( 41 // CHECK-O1-SAME: ) local_unnamed_addr #[[ATTR0]] { 42 // CHECK-O1-NEXT: entry: 43 // CHECK-O1-NEXT: ret i32 2 44 // 45 int test_popcountg_ubi2() { 46 unsigned _BitInt(2) a = 3uwb; 47 return __builtin_popcountg(a); 48 } 49 50 // CHECK-O0-LABEL: define dso_local arm_aapcscc i32 @test_ctzg_ubi1( 51 // CHECK-O0-SAME: ) #[[ATTR0]] { 52 // CHECK-O0-NEXT: entry: 53 // CHECK-O0-NEXT: [[A:%.*]] = alloca i8, align 1 54 // CHECK-O0-NEXT: store i8 0, ptr [[A]], align 1 55 // CHECK-O0-NEXT: [[TMP0:%.*]] = load i8, ptr [[A]], align 1 56 // CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1 57 // CHECK-O0-NEXT: [[TMP1:%.*]] = call i1 @llvm.cttz.i1(i1 [[LOADEDV]], i1 false) 58 // CHECK-O0-NEXT: [[CAST:%.*]] = zext i1 [[TMP1]] to i32 59 // CHECK-O0-NEXT: ret i32 [[CAST]] 60 // 61 // CHECK-O1-LABEL: define dso_local arm_aapcscc noundef i32 @test_ctzg_ubi1( 62 // CHECK-O1-SAME: ) local_unnamed_addr #[[ATTR0]] { 63 // CHECK-O1-NEXT: entry: 64 // CHECK-O1-NEXT: ret i32 1 65 // 66 int test_ctzg_ubi1() { 67 unsigned _BitInt(1) a = 0uwb; 68 return __builtin_ctzg(a); 69 } 70 71 // CHECK-O0-LABEL: define dso_local arm_aapcscc i32 @test_ctzg_ubi2( 72 // CHECK-O0-SAME: ) #[[ATTR0]] { 73 // CHECK-O0-NEXT: entry: 74 // CHECK-O0-NEXT: [[A:%.*]] = alloca i8, align 1 75 // CHECK-O0-NEXT: store i8 0, ptr [[A]], align 1 76 // CHECK-O0-NEXT: [[TMP0:%.*]] = load i8, ptr [[A]], align 1 77 // CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i2 78 // CHECK-O0-NEXT: [[TMP1:%.*]] = call i2 @llvm.cttz.i2(i2 [[LOADEDV]], i1 false) 79 // CHECK-O0-NEXT: [[CAST:%.*]] = zext i2 [[TMP1]] to i32 80 // CHECK-O0-NEXT: ret i32 [[CAST]] 81 // 82 // CHECK-O1-LABEL: define dso_local arm_aapcscc noundef i32 @test_ctzg_ubi2( 83 // CHECK-O1-SAME: ) local_unnamed_addr #[[ATTR0]] { 84 // CHECK-O1-NEXT: entry: 85 // CHECK-O1-NEXT: ret i32 2 86 // 87 int test_ctzg_ubi2() { 88 unsigned _BitInt(2) a = 0uwb; 89 return __builtin_ctzg(a); 90 } 91 92 // CHECK-O0-LABEL: define dso_local arm_aapcscc i32 @test_clzg_ubi1( 93 // CHECK-O0-SAME: ) #[[ATTR0]] { 94 // CHECK-O0-NEXT: entry: 95 // CHECK-O0-NEXT: [[A:%.*]] = alloca i8, align 1 96 // CHECK-O0-NEXT: store i8 0, ptr [[A]], align 1 97 // CHECK-O0-NEXT: [[TMP0:%.*]] = load i8, ptr [[A]], align 1 98 // CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1 99 // CHECK-O0-NEXT: [[TMP1:%.*]] = call i1 @llvm.ctlz.i1(i1 [[LOADEDV]], i1 false) 100 // CHECK-O0-NEXT: [[CAST:%.*]] = zext i1 [[TMP1]] to i32 101 // CHECK-O0-NEXT: ret i32 [[CAST]] 102 // 103 // CHECK-O1-LABEL: define dso_local arm_aapcscc noundef i32 @test_clzg_ubi1( 104 // CHECK-O1-SAME: ) local_unnamed_addr #[[ATTR0]] { 105 // CHECK-O1-NEXT: entry: 106 // CHECK-O1-NEXT: ret i32 1 107 // 108 int test_clzg_ubi1() { 109 unsigned _BitInt(1) a = 0uwb; 110 return __builtin_clzg(a); 111 } 112 113 // CHECK-O0-LABEL: define dso_local arm_aapcscc i32 @test_clzg_ubi2( 114 // CHECK-O0-SAME: ) #[[ATTR0]] { 115 // CHECK-O0-NEXT: entry: 116 // CHECK-O0-NEXT: [[A:%.*]] = alloca i8, align 1 117 // CHECK-O0-NEXT: store i8 0, ptr [[A]], align 1 118 // CHECK-O0-NEXT: [[TMP0:%.*]] = load i8, ptr [[A]], align 1 119 // CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i2 120 // CHECK-O0-NEXT: [[TMP1:%.*]] = call i2 @llvm.ctlz.i2(i2 [[LOADEDV]], i1 false) 121 // CHECK-O0-NEXT: [[CAST:%.*]] = zext i2 [[TMP1]] to i32 122 // CHECK-O0-NEXT: ret i32 [[CAST]] 123 // 124 // CHECK-O1-LABEL: define dso_local arm_aapcscc noundef i32 @test_clzg_ubi2( 125 // CHECK-O1-SAME: ) local_unnamed_addr #[[ATTR0]] { 126 // CHECK-O1-NEXT: entry: 127 // CHECK-O1-NEXT: ret i32 2 128 // 129 int test_clzg_ubi2() { 130 unsigned _BitInt(2) a = 0uwb; 131 return __builtin_clzg(a); 132 } 133