236 lines · plain
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 52// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O3 -o - -triple=amdgcn-amd-amdhsa \3// RUN: | FileCheck %s --check-prefix=AMDGCN4// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O3 -o - -triple=spirv64-unknown-unknown \5// RUN: | FileCheck %s --check-prefix=SPIRV6 7// AMDGCN-LABEL: define dso_local i32 @load(8// AMDGCN-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {9// AMDGCN-NEXT: [[ENTRY:.*:]]10// AMDGCN-NEXT: [[TMP0:%.*]] = load atomic i32, ptr [[P]] syncscope("agent") seq_cst, align 411// AMDGCN-NEXT: ret i32 [[TMP0]]12//13// SPIRV-LABEL: define spir_func i32 @load(14// SPIRV-SAME: ptr addrspace(4) noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {15// SPIRV-NEXT: [[ENTRY:.*:]]16// SPIRV-NEXT: [[TMP0:%.*]] = load atomic i32, ptr addrspace(4) [[P]] syncscope("device") seq_cst, align 417// SPIRV-NEXT: ret i32 [[TMP0]]18//19int load(int *p) { return __atomic_load_n(p, __ATOMIC_SEQ_CST); }20// AMDGCN-LABEL: define dso_local void @store(21// AMDGCN-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {22// AMDGCN-NEXT: [[ENTRY:.*:]]23// AMDGCN-NEXT: store atomic i32 [[X]], ptr [[P]] syncscope("agent") seq_cst, align 424// AMDGCN-NEXT: ret void25//26// SPIRV-LABEL: define spir_func void @store(27// SPIRV-SAME: ptr addrspace(4) noundef writeonly captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {28// SPIRV-NEXT: [[ENTRY:.*:]]29// SPIRV-NEXT: store atomic i32 [[X]], ptr addrspace(4) [[P]] syncscope("device") seq_cst, align 430// SPIRV-NEXT: ret void31//32void store(int *p, int x) { return __atomic_store_n(p, x, __ATOMIC_SEQ_CST); }33// AMDGCN-LABEL: define dso_local i32 @add(34// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {35// AMDGCN-NEXT: [[ENTRY:.*:]]36// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw add ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 437// AMDGCN-NEXT: ret i32 [[TMP0]]38//39// SPIRV-LABEL: define spir_func i32 @add(40// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {41// SPIRV-NEXT: [[ENTRY:.*:]]42// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw add ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 443// SPIRV-NEXT: ret i32 [[TMP0]]44//45int add(int *p, int x) { return __atomic_fetch_add(p, x, __ATOMIC_SEQ_CST); }46// AMDGCN-LABEL: define dso_local float @fadd(47// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {48// AMDGCN-NEXT: [[ENTRY:.*:]]49// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 450// AMDGCN-NEXT: ret float [[TMP0]]51//52// SPIRV-LABEL: define spir_func float @fadd(53// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {54// SPIRV-NEXT: [[ENTRY:.*:]]55// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 456// SPIRV-NEXT: ret float [[TMP0]]57//58float fadd(float *p, float x) { return __atomic_fetch_add(p, x, __ATOMIC_SEQ_CST); }59// AMDGCN-LABEL: define dso_local i32 @sub(60// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {61// AMDGCN-NEXT: [[ENTRY:.*:]]62// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw sub ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 463// AMDGCN-NEXT: ret i32 [[TMP0]]64//65// SPIRV-LABEL: define spir_func i32 @sub(66// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {67// SPIRV-NEXT: [[ENTRY:.*:]]68// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw sub ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 469// SPIRV-NEXT: ret i32 [[TMP0]]70//71int sub(int *p, int x) { return __atomic_fetch_sub(p, x, __ATOMIC_SEQ_CST); }72// AMDGCN-LABEL: define dso_local float @fsub(73// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {74// AMDGCN-NEXT: [[ENTRY:.*:]]75// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 476// AMDGCN-NEXT: ret float [[TMP0]]77//78// SPIRV-LABEL: define spir_func float @fsub(79// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {80// SPIRV-NEXT: [[ENTRY:.*:]]81// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 482// SPIRV-NEXT: ret float [[TMP0]]83//84float fsub(float *p, float x) { return __atomic_fetch_sub(p, x, __ATOMIC_SEQ_CST); }85// AMDGCN-LABEL: define dso_local i32 @and(86// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {87// AMDGCN-NEXT: [[ENTRY:.*:]]88// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw and ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 489// AMDGCN-NEXT: ret i32 [[TMP0]]90//91// SPIRV-LABEL: define spir_func i32 @and(92// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {93// SPIRV-NEXT: [[ENTRY:.*:]]94// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw and ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 495// SPIRV-NEXT: ret i32 [[TMP0]]96//97int and(int *p, int x) { return __atomic_fetch_and(p, x, __ATOMIC_SEQ_CST); }98// AMDGCN-LABEL: define dso_local i32 @nand(99// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {100// AMDGCN-NEXT: [[ENTRY:.*:]]101// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw nand ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4102// AMDGCN-NEXT: ret i32 [[TMP0]]103//104// SPIRV-LABEL: define spir_func i32 @nand(105// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {106// SPIRV-NEXT: [[ENTRY:.*:]]107// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw nand ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4108// SPIRV-NEXT: ret i32 [[TMP0]]109//110int nand(int *p, int x) { return __atomic_fetch_nand(p, x, __ATOMIC_SEQ_CST); }111// AMDGCN-LABEL: define dso_local i32 @or(112// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {113// AMDGCN-NEXT: [[ENTRY:.*:]]114// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw or ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4115// AMDGCN-NEXT: ret i32 [[TMP0]]116//117// SPIRV-LABEL: define spir_func i32 @or(118// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {119// SPIRV-NEXT: [[ENTRY:.*:]]120// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw or ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4121// SPIRV-NEXT: ret i32 [[TMP0]]122//123int or(int *p, int x) { return __atomic_fetch_or(p, x, __ATOMIC_SEQ_CST); }124// AMDGCN-LABEL: define dso_local i32 @xor(125// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {126// AMDGCN-NEXT: [[ENTRY:.*:]]127// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw xor ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4128// AMDGCN-NEXT: ret i32 [[TMP0]]129//130// SPIRV-LABEL: define spir_func i32 @xor(131// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {132// SPIRV-NEXT: [[ENTRY:.*:]]133// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw xor ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4134// SPIRV-NEXT: ret i32 [[TMP0]]135//136int xor(int *p, int x) { return __atomic_fetch_xor(p, x, __ATOMIC_SEQ_CST); }137// AMDGCN-LABEL: define dso_local i32 @min(138// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {139// AMDGCN-NEXT: [[ENTRY:.*:]]140// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw min ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4141// AMDGCN-NEXT: ret i32 [[TMP0]]142//143// SPIRV-LABEL: define spir_func i32 @min(144// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {145// SPIRV-NEXT: [[ENTRY:.*:]]146// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw min ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4147// SPIRV-NEXT: ret i32 [[TMP0]]148//149int min(int *p, int x) { return __atomic_fetch_min(p, x, __ATOMIC_SEQ_CST); }150// AMDGCN-LABEL: define dso_local float @fmin(151// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {152// AMDGCN-NEXT: [[ENTRY:.*:]]153// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fmin ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4154// AMDGCN-NEXT: ret float [[TMP0]]155//156// SPIRV-LABEL: define spir_func float @fmin(157// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {158// SPIRV-NEXT: [[ENTRY:.*:]]159// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fmin ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4160// SPIRV-NEXT: ret float [[TMP0]]161//162float fmin(float *p, float x) { return __atomic_fetch_min(p, x, __ATOMIC_SEQ_CST); }163// AMDGCN-LABEL: define dso_local i32 @max(164// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {165// AMDGCN-NEXT: [[ENTRY:.*:]]166// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw max ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4167// AMDGCN-NEXT: ret i32 [[TMP0]]168//169// SPIRV-LABEL: define spir_func i32 @max(170// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {171// SPIRV-NEXT: [[ENTRY:.*:]]172// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw max ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4173// SPIRV-NEXT: ret i32 [[TMP0]]174//175int max(int *p, int x) { return __atomic_fetch_max(p, x, __ATOMIC_SEQ_CST); }176// AMDGCN-LABEL: define dso_local float @fmax(177// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {178// AMDGCN-NEXT: [[ENTRY:.*:]]179// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fmax ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4180// AMDGCN-NEXT: ret float [[TMP0]]181//182// SPIRV-LABEL: define spir_func float @fmax(183// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {184// SPIRV-NEXT: [[ENTRY:.*:]]185// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fmax ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4186// SPIRV-NEXT: ret float [[TMP0]]187//188float fmax(float *p, float x) { return __atomic_fetch_max(p, x, __ATOMIC_SEQ_CST); }189// AMDGCN-LABEL: define dso_local i32 @xchg(190// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {191// AMDGCN-NEXT: [[ENTRY:.*:]]192// AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw xchg ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4193// AMDGCN-NEXT: ret i32 [[TMP0]]194//195// SPIRV-LABEL: define spir_func i32 @xchg(196// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {197// SPIRV-NEXT: [[ENTRY:.*:]]198// SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw xchg ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4199// SPIRV-NEXT: ret i32 [[TMP0]]200//201int xchg(int *p, int x) { return __atomic_exchange_n(p, x, __ATOMIC_SEQ_CST); }202// AMDGCN-LABEL: define dso_local range(i32 0, 2) i32 @cmpxchg(203// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {204// AMDGCN-NEXT: [[ENTRY:.*:]]205// AMDGCN-NEXT: [[TMP0:%.*]] = cmpxchg ptr [[P]], i32 [[X]], i32 [[Y]] syncscope("agent") seq_cst seq_cst, align 4206// AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1207// AMDGCN-NEXT: [[CONV:%.*]] = zext i1 [[TMP1]] to i32208// AMDGCN-NEXT: ret i32 [[CONV]]209//210// SPIRV-LABEL: define spir_func range(i32 0, 2) i32 @cmpxchg(211// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {212// SPIRV-NEXT: [[ENTRY:.*:]]213// SPIRV-NEXT: [[TMP0:%.*]] = cmpxchg ptr addrspace(4) [[P]], i32 [[X]], i32 [[Y]] syncscope("device") seq_cst seq_cst, align 4214// SPIRV-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1215// SPIRV-NEXT: [[CONV:%.*]] = zext i1 [[TMP1]] to i32216// SPIRV-NEXT: ret i32 [[CONV]]217//218int cmpxchg(int *p, int x, int y) { return __atomic_compare_exchange(p, &x, &y, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }219// AMDGCN-LABEL: define dso_local range(i32 0, 2) i32 @cmpxchg_weak(220// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {221// AMDGCN-NEXT: [[ENTRY:.*:]]222// AMDGCN-NEXT: [[TMP0:%.*]] = cmpxchg weak ptr [[P]], i32 [[X]], i32 [[Y]] syncscope("agent") seq_cst seq_cst, align 4223// AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1224// AMDGCN-NEXT: [[CONV:%.*]] = zext i1 [[TMP1]] to i32225// AMDGCN-NEXT: ret i32 [[CONV]]226//227// SPIRV-LABEL: define spir_func range(i32 0, 2) i32 @cmpxchg_weak(228// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {229// SPIRV-NEXT: [[ENTRY:.*:]]230// SPIRV-NEXT: [[TMP0:%.*]] = cmpxchg weak ptr addrspace(4) [[P]], i32 [[X]], i32 [[Y]] syncscope("device") seq_cst seq_cst, align 4231// SPIRV-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1232// SPIRV-NEXT: [[CONV:%.*]] = zext i1 [[TMP1]] to i32233// SPIRV-NEXT: ret i32 [[CONV]]234//235int cmpxchg_weak(int *p, int x, int y) { return __atomic_compare_exchange(p, &x, &y, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }236