1; RUN: opt -mtriple=amdgcn-amd-amdhsa -amdgpu-codegenprepare -verify -S %s -o - | FileCheck %s
2
3declare i1 @llvm.amdgcn.class.f32(float, i32) nounwind readnone
4declare i1 @llvm.amdgcn.class.f64(double, i32) nounwind readnone
5
6; Trivial case, xor instruction should be removed and
7; the second argument of the intrinsic call should be
8; bitwise-negated
9; CHECK: @fold_negate_intrinsic_test_mask
10; CHECK: %1 = call i1 @llvm.amdgcn.class.f32(float %x, i32 1018)
11define i1 @fold_negate_intrinsic_test_mask(float %x) nounwind {
12  %1 = call i1 @llvm.amdgcn.class.f32(float %x, i32 5)
13  %2 = xor i1 %1, -1
14  ret i1 %2
15}
16
17; Trivial case, xor instruction should be removed and
18; the second argument of the intrinsic call should be
19; bitwise-negated
20; CHECK: @fold_negate_intrinsic_test_mask_dbl
21; CHECK: %1 = call i1 @llvm.amdgcn.class.f64(double %x, i32 1018)
22define i1 @fold_negate_intrinsic_test_mask_dbl(double %x) nounwind {
23  %1 = call i1 @llvm.amdgcn.class.f64(double %x, i32 5)
24  %2 = xor i1 %1, -1
25  ret i1 %2
26}
27
28; Negative test: should not transform for variable test masks
29; CHECK: @fold_negate_intrinsic_test_mask_neg_var
30; CHECK: %[[X0:.*]] = alloca i32
31; CHECK: %[[X1:.*]] = load i32, i32* %[[X0]]
32; CHECK: call i1 @llvm.amdgcn.class.f32(float %x, i32 %[[X1]])
33; CHECK: xor
34define i1 @fold_negate_intrinsic_test_mask_neg_var(float %x) nounwind {
35  %1 = alloca i32
36  store i32 7, i32* %1
37  %2 = load i32, i32* %1
38  %3 = call i1 @llvm.amdgcn.class.f32(float %x, i32 %2)
39  %4 = xor i1 %3, -1
40  ret i1 %4
41}
42
43; Negative test: should not transform for multiple uses of the
44;   intrinsic returned value
45; CHECK: @fold_negate_intrinsic_test_mask_neg_multiple_uses
46; CHECK: %[[X1:.*]] = call i1 @llvm.amdgcn.class.f32(float %x, i32 7)
47; CHECK: store i1 %[[X1]]
48; CHECK: %[[X2:.*]] = xor i1 %[[X1]]
49define i1 @fold_negate_intrinsic_test_mask_neg_multiple_uses(float %x) nounwind {
50  %y = alloca i1
51  %1 = call i1 @llvm.amdgcn.class.f32(float %x, i32 7)
52  %2 = xor i1 %1, -1
53  store i1 %1, i1* %y
54  %3 = xor i1 %1, -1
55  ret i1 %2
56}
57
58; Negative test: should not transform for a xor with no operand equal to -1
59; CHECK: @fold_negate_intrinsic_test_mask_neg_one
60; CHECK: %[[X0:.*]] = call i1 @llvm.amdgcn.class.f32(float %x, i32 7)
61; CHECK: xor i1 %[[X0]], false
62define i1 @fold_negate_intrinsic_test_mask_neg_one(float %x) nounwind {
63  %1 = call i1 @llvm.amdgcn.class.f32(float %x, i32 7)
64  %2 = xor i1 %1, false
65  ret i1 %2
66}
67