blob: 327d68bdf550e443b0237264b4a7a5136b86b0bd [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine < %s | FileCheck -check-prefixes=CHECK,WAVE64 %s
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mattr=+wavefrontsize32 -passes=instcombine < %s | FileCheck -check-prefixes=CHECK,WAVE32 %s
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mattr=+wavefrontsize64 -passes=instcombine < %s | FileCheck -check-prefixes=CHECK,WAVE64 %s
; --------------------------------------------------------------------
; llvm.amdgcn.readlane
; --------------------------------------------------------------------
define i32 @readlane_31(i32 %arg) #0 {
; CHECK-LABEL: define i32 @readlane_31(
; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 31)
; CHECK-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 31)
ret i32 %res
}
define i32 @readlane_32(i32 %arg) #0 {
; WAVE64-LABEL: define i32 @readlane_32(
; WAVE64-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 32)
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @readlane_32(
; WAVE32-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 0)
; WAVE32-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 32)
ret i32 %res
}
define i32 @readlane_33(i32 %arg) #0 {
; WAVE64-LABEL: define i32 @readlane_33(
; WAVE64-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 33)
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @readlane_33(
; WAVE32-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 1)
; WAVE32-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 33)
ret i32 %res
}
define i32 @readlane_63(i32 %arg) #0 {
; WAVE64-LABEL: define i32 @readlane_63(
; WAVE64-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 63)
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @readlane_63(
; WAVE32-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 31)
; WAVE32-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 63)
ret i32 %res
}
define i32 @readlane_64(i32 %arg) #0 {
; CHECK-LABEL: define i32 @readlane_64(
; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 0)
; CHECK-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 64)
ret i32 %res
}
define i32 @readlane_and_31(i32 %arg, i32 %idx) #0 {
; WAVE64-LABEL: define i32 @readlane_and_31(
; WAVE64-SAME: i32 [[ARG:%.*]], i32 [[IDX:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[IDX_CLAMP:%.*]] = and i32 [[IDX]], 31
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 [[IDX_CLAMP]])
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @readlane_and_31(
; WAVE32-SAME: i32 [[ARG:%.*]], i32 [[IDX:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 [[IDX]])
; WAVE32-NEXT: ret i32 [[RES]]
;
%idx.clamp = and i32 %idx, 31
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 %idx.clamp)
ret i32 %res
}
define i32 @readlane_and_63(i32 %arg, i32 %idx) #0 {
; CHECK-LABEL: define i32 @readlane_and_63(
; CHECK-SAME: i32 [[ARG:%.*]], i32 [[IDX:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 [[IDX]])
; CHECK-NEXT: ret i32 [[RES]]
;
%idx.clamp = and i32 %idx, 63
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 %idx.clamp)
ret i32 %res
}
define i32 @readlane_poison(i32 %arg) #0 {
; CHECK-LABEL: define i32 @readlane_poison(
; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.readlane.i32(i32 [[ARG]], i32 poison)
; CHECK-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.readlane.i32(i32 %arg, i32 poison)
ret i32 %res
}
define float @readlane_f32_63(float %arg) #0 {
; WAVE64-LABEL: define float @readlane_f32_63(
; WAVE64-SAME: float [[ARG:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call float @llvm.amdgcn.readlane.f32(float [[ARG]], i32 63)
; WAVE64-NEXT: ret float [[RES]]
;
; WAVE32-LABEL: define float @readlane_f32_63(
; WAVE32-SAME: float [[ARG:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call float @llvm.amdgcn.readlane.f32(float [[ARG]], i32 31)
; WAVE32-NEXT: ret float [[RES]]
;
%res = call float @llvm.amdgcn.readlane.f32(float %arg, i32 63)
ret float %res
}
; --------------------------------------------------------------------
; llvm.amdgcn.writelane
; --------------------------------------------------------------------
define i32 @writelane_31(i32 %arg0, i32 %arg1) #0 {
; CHECK-LABEL: define i32 @writelane_31(
; CHECK-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 31, i32 [[ARG1]])
; CHECK-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 31, i32 %arg1)
ret i32 %res
}
define i32 @writelane_32(i32 %arg0, i32 %arg1) #0 {
; WAVE64-LABEL: define i32 @writelane_32(
; WAVE64-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 32, i32 [[ARG1]])
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @writelane_32(
; WAVE32-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 0, i32 [[ARG1]])
; WAVE32-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 32, i32 %arg1)
ret i32 %res
}
define i32 @writelane_33(i32 %arg0, i32 %arg1) #0 {
; WAVE64-LABEL: define i32 @writelane_33(
; WAVE64-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 33, i32 [[ARG1]])
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @writelane_33(
; WAVE32-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 1, i32 [[ARG1]])
; WAVE32-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 33, i32 %arg1)
ret i32 %res
}
define i32 @writelane_63(i32 %arg0, i32 %arg1) #0 {
; WAVE64-LABEL: define i32 @writelane_63(
; WAVE64-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 63, i32 [[ARG1]])
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @writelane_63(
; WAVE32-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 31, i32 [[ARG1]])
; WAVE32-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 63, i32 %arg1)
ret i32 %res
}
define i32 @writelane_64(i32 %arg0, i32 %arg1) #0 {
; CHECK-LABEL: define i32 @writelane_64(
; CHECK-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 0, i32 [[ARG1]])
; CHECK-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 64, i32 %arg1)
ret i32 %res
}
define i32 @writelane_and_31(i32 %arg0, i32 %arg1, i32 %idx) #0 {
; WAVE64-LABEL: define i32 @writelane_and_31(
; WAVE64-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]], i32 [[IDX:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[IDX_CLAMP:%.*]] = and i32 [[IDX]], 31
; WAVE64-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 [[IDX_CLAMP]], i32 [[ARG1]])
; WAVE64-NEXT: ret i32 [[RES]]
;
; WAVE32-LABEL: define i32 @writelane_and_31(
; WAVE32-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]], i32 [[IDX:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 [[IDX]], i32 [[ARG1]])
; WAVE32-NEXT: ret i32 [[RES]]
;
%idx.clamp = and i32 %idx, 31
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 %idx.clamp, i32 %arg1)
ret i32 %res
}
define i32 @writelane_and_63(i32 %arg0, i32 %arg1, i32 %idx) #0 {
; CHECK-LABEL: define i32 @writelane_and_63(
; CHECK-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]], i32 [[IDX:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 [[IDX]], i32 [[ARG1]])
; CHECK-NEXT: ret i32 [[RES]]
;
%idx.clamp = and i32 %idx, 63
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 %idx.clamp, i32 %arg1)
ret i32 %res
}
define i32 @writelane_poison(i32 %arg0, i32 %arg1) #0 {
; CHECK-LABEL: define i32 @writelane_poison(
; CHECK-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.writelane.i32(i32 [[ARG0]], i32 poison, i32 [[ARG1]])
; CHECK-NEXT: ret i32 [[RES]]
;
%res = call i32 @llvm.amdgcn.writelane.i32(i32 %arg0, i32 poison, i32 %arg1)
ret i32 %res
}
define float @writelane_f32_63(float %arg0, float %arg1) #0 {
; WAVE64-LABEL: define float @writelane_f32_63(
; WAVE64-SAME: float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE64-NEXT: [[RES:%.*]] = call float @llvm.amdgcn.writelane.f32(float [[ARG0]], i32 63, float [[ARG1]])
; WAVE64-NEXT: ret float [[RES]]
;
; WAVE32-LABEL: define float @writelane_f32_63(
; WAVE32-SAME: float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR0]] {
; WAVE32-NEXT: [[RES:%.*]] = call float @llvm.amdgcn.writelane.f32(float [[ARG0]], i32 31, float [[ARG1]])
; WAVE32-NEXT: ret float [[RES]]
;
%res = call float @llvm.amdgcn.writelane.f32(float %arg0, i32 63, float %arg1)
ret float %res
}
attributes #0 = { nounwind }