98 lines · c
1// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-unknown-unknown -target-feature +rdrnd -target-feature +rdseed -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,X642// RUN: %clang_cc1 -ffreestanding %s -triple=i386-unknown-unknown -target-feature +rdrnd -target-feature +rdseed -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,X863 4#include <immintrin.h>5 6int rdrand16(unsigned short *p) {7 return _rdrand16_step(p);8// CHECK: @rdrand169// CHECK: call { i16, i32 } @llvm.x86.rdrand.1610// CHECK: store i1611}12 13int rdrand32(unsigned *p) {14 return _rdrand32_step(p);15// CHECK: @rdrand3216// CHECK: call { i32, i32 } @llvm.x86.rdrand.3217// CHECK: store i3218}19 20int rdrand64(unsigned long long *p) {21 return _rdrand64_step(p);22// X64: @rdrand6423// X64: call { i64, i32 } @llvm.x86.rdrand.6424// X64: store i6425 26// X86-LABEL: @rdrand64(27// X86-NEXT: entry:28// X86-NEXT: [[RETVAL_I:%.*]] = alloca i32, align 429// X86-NEXT: [[__P_ADDR_I:%.*]] = alloca ptr, align 430// X86-NEXT: [[__LO_I:%.*]] = alloca i32, align 431// X86-NEXT: [[__HI_I:%.*]] = alloca i32, align 432// X86-NEXT: [[__RES_LO_I:%.*]] = alloca i32, align 433// X86-NEXT: [[__RES_HI_I:%.*]] = alloca i32, align 434// X86-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 435// X86-NEXT: store ptr [[P:%.*]], ptr [[P_ADDR]], align 436// X86-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 437// X86-NEXT: store ptr [[TMP0]], ptr [[__P_ADDR_I]], align 438// X86-NEXT: [[TMP1:%.*]] = call { i32, i32 } @llvm.x86.rdrand.32()39// X86-NEXT: [[TMP2:%.*]] = extractvalue { i32, i32 } [[TMP1]], 040// X86-NEXT: store i32 [[TMP2]], ptr [[__LO_I]], align 441// X86-NEXT: [[TMP3:%.*]] = extractvalue { i32, i32 } [[TMP1]], 142// X86-NEXT: store i32 [[TMP3]], ptr [[__RES_LO_I]], align 443// X86-NEXT: [[TMP4:%.*]] = call { i32, i32 } @llvm.x86.rdrand.32()44// X86-NEXT: [[TMP5:%.*]] = extractvalue { i32, i32 } [[TMP4]], 045// X86-NEXT: store i32 [[TMP5]], ptr [[__HI_I]], align 446// X86-NEXT: [[TMP6:%.*]] = extractvalue { i32, i32 } [[TMP4]], 147// X86-NEXT: store i32 [[TMP6]], ptr [[__RES_HI_I]], align 448// X86-NEXT: [[TMP7:%.*]] = load i32, ptr [[__RES_LO_I]], align 449// X86-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[TMP7]], 050// X86-NEXT: br i1 [[TOBOOL_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[IF_ELSE_I:%.*]]51// X86: land.lhs.true.i:52// X86-NEXT: [[TMP8:%.*]] = load i32, ptr [[__RES_HI_I]], align 453// X86-NEXT: [[TOBOOL1_I:%.*]] = icmp ne i32 [[TMP8]], 054// X86-NEXT: br i1 [[TOBOOL1_I]], label [[IF_THEN_I:%.*]], label [[IF_ELSE_I]]55// X86: if.then.i:56// X86-NEXT: [[TMP9:%.*]] = load i32, ptr [[__HI_I]], align 457// X86-NEXT: [[CONV_I:%.*]] = zext i32 [[TMP9]] to i6458// X86-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV_I]], 3259// X86-NEXT: [[TMP10:%.*]] = load i32, ptr [[__LO_I]], align 460// X86-NEXT: [[CONV2_I:%.*]] = zext i32 [[TMP10]] to i6461// X86-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV2_I]]62// X86-NEXT: [[TMP11:%.*]] = load ptr, ptr [[__P_ADDR_I]], align 463// X86-NEXT: store i64 [[OR_I]], ptr [[TMP11]], align 464// X86-NEXT: store i32 1, ptr [[RETVAL_I]], align 465// X86-NEXT: br label [[_RDRAND64_STEP_EXIT:%.*]]66// X86: if.else.i:67// X86-NEXT: [[TMP12:%.*]] = load ptr, ptr [[__P_ADDR_I]], align 468// X86-NEXT: store i64 0, ptr [[TMP12]], align 469// X86-NEXT: store i32 0, ptr [[RETVAL_I]], align 470// X86-NEXT: br label [[_RDRAND64_STEP_EXIT]]71// X86: _rdrand64_step.exit:72// X86-NEXT: [[TMP13:%.*]] = load i32, ptr [[RETVAL_I]], align 473// X86-NEXT: ret i32 [[TMP13]]74}75 76int rdseed16(unsigned short *p) {77 return _rdseed16_step(p);78// CHECK: @rdseed1679// CHECK: call { i16, i32 } @llvm.x86.rdseed.1680// CHECK: store i1681}82 83int rdseed32(unsigned *p) {84 return _rdseed32_step(p);85// CHECK: @rdseed3286// CHECK: call { i32, i32 } @llvm.x86.rdseed.3287// CHECK: store i3288}89 90#if __x86_64__91int rdseed64(unsigned long long *p) {92 return _rdseed64_step(p);93// X64: @rdseed6494// X64: call { i64, i32 } @llvm.x86.rdseed.6495// X64: store i6496}97#endif98