llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

<details>
<summary>Changes</summary>

This extends the UnaryOp folder to handle plus, minus, and not operations on 
constant operands.

This is in preparation for a change that will attempt to fold these unary 
operations as they are generated, but this change only performs the folding via 
the cir-canonicalize pass.

---

Patch is 20.01 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/174882.diff


11 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+6) 
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+31) 
- (modified) clang/test/CIR/CodeGen/basic.c (+3-6) 
- (modified) clang/test/CIR/CodeGen/basic.cpp (+3-10) 
- (modified) clang/test/CIR/CodeGen/bitfields_be.c (+5-7) 
- (modified) clang/test/CIR/CodeGen/goto.cpp (+2-3) 
- (modified) clang/test/CIR/CodeGen/pointers.cpp (+11-8) 
- (modified) clang/test/CIR/CodeGen/switch.cpp (+2-3) 
- (modified) clang/test/CIR/CodeGen/ternary.cpp (+1-2) 
- (modified) clang/test/CIR/Lowering/goto.cir (+4-6) 
- (modified) clang/test/CIR/Transforms/canonicalize.cir (+185-2) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4274ed25542b1..fc76e41885435 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -420,6 +420,12 @@ def CIR_ConstantOp : CIR_Op<"const", [
       llvm_unreachable("Expected an IntAttr in ConstantOp");
     }
 
+    llvm::APFloat getFloatValue() {
+      if (const auto fpAttr = getValueAttr<cir::FPAttr>())
+        return fpAttr.getValue();
+      llvm_unreachable("Expected an FPAttr in ConstantOp");
+    }
+
     bool getBoolValue() {
       if (const auto boolAttr = getValueAttr<cir::BoolAttr>())
         return boolAttr.getValue();
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index a17dade12ed24..e80d858e39e43 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2479,6 +2479,37 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) {
       if (isBoolNot(previous))
         return previous.getInput();
 
+  // Fold constant unary operations.
+  if (auto srcConst = getInput().getDefiningOp<cir::ConstantOp>()) {
+    switch (getKind()) {
+    case cir::UnaryOpKind::Not:
+      if (mlir::isa<cir::IntType>(srcConst.getType())) {
+        APInt val = srcConst.getIntValue();
+        val.flipAllBits();
+        return cir::IntAttr::get(getType(), val);
+      }
+      assert(mlir::isa<cir::BoolType>(srcConst.getType()));
+      return cir::BoolAttr::get(getContext(), !srcConst.getBoolValue());
+    case cir::UnaryOpKind::Plus:
+      return srcConst.getResult();
+    case cir::UnaryOpKind::Minus:
+      if (mlir::isa<cir::FPTypeInterface>(srcConst.getType())) {
+        APFloat val = srcConst.getFloatValue();
+        val.changeSign();
+        return cir::FPAttr::get(getType(), val);
+      }
+      if (mlir::isa<cir::IntType>(srcConst.getType())) {
+        APInt val = srcConst.getIntValue();
+        val.negate();
+        return cir::IntAttr::get(getType(), val);
+      }
+      assert(mlir::isa<cir::BoolType>(srcConst.getType()));
+      return srcConst.getResult();
+    default:
+      return {};
+    }
+  }
+
   return {};
 }
 
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index 9268615bc9fb0..4646e5b771f8b 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -293,12 +293,9 @@ size_type max_size(void) {
 }
 
 // CIR: cir.func{{.*}} @max_size()
-// CIR:   %0 = cir.alloca !u64i, !cir.ptr<!u64i>, ["__retval"] {alignment = 8 
: i64}
-// CIR:   %1 = cir.const #cir.int<0> : !s32i
-// CIR:   %2 = cir.unary(not, %1) : !s32i, !s32i
-// CIR:   %3 = cir.cast integral %2 : !s32i -> !u64i
-// CIR:   %4 = cir.const #cir.int<8> : !u64i
-// CIR:   %5 = cir.binop(div, %3, %4) : !u64i
+// CIR:   %[[NOT_ZERO:.*]] = cir.const #cir.int<18446744073709551615> : !u64i
+// CIR:   %[[SIZE_OF_TP:.*]] = cir.const #cir.int<8> : !u64i
+// CIR:   %[[RESULT:.*]] = cir.binop(div, %[[NOT_ZERO]], %[[SIZE_OF_TP]]) : 
!u64i
 
 // LLVM: define{{.*}} i64 @max_size()
 // LLVM:   store i64 2305843009213693951, ptr
diff --git a/clang/test/CIR/CodeGen/basic.cpp b/clang/test/CIR/CodeGen/basic.cpp
index af8de6fff047a..245a43710bf71 100644
--- a/clang/test/CIR/CodeGen/basic.cpp
+++ b/clang/test/CIR/CodeGen/basic.cpp
@@ -121,16 +121,9 @@ size_type max_size() {
 }
 
 // CHECK: cir.func{{.*}} @_Z8max_sizev() -> !u64i
-// CHECK:   %0 = cir.alloca !u64i, !cir.ptr<!u64i>, ["__retval"] {alignment = 
8 : i64}
-// CHECK:   %1 = cir.const #cir.int<0> : !s32i
-// CHECK:   %2 = cir.unary(not, %1) : !s32i, !s32i
-// CHECK:   %3 = cir.cast integral %2 : !s32i -> !u64i
-// CHECK:   %4 = cir.const #cir.int<8> : !u64i
-// CHECK:   %5 = cir.binop(div, %3, %4) : !u64i
-// CHECK:   cir.store{{.*}} %5, %0 : !u64i, !cir.ptr<!u64i>
-// CHECK:   %6 = cir.load{{.*}} %0 : !cir.ptr<!u64i>, !u64i
-// CHECK:   cir.return %6 : !u64i
-// CHECK:   }
+// CHECK:   %[[NOT_ZERO:.*]] = cir.const #cir.int<18446744073709551615> : !u64i
+// CHECK:   %[[SIZE_OF_TP:.*]] = cir.const #cir.int<8> : !u64i
+// CHECK:   %[[RESULT:.*]] = cir.binop(div, %[[NOT_ZERO]], %[[SIZE_OF_TP]]) : 
!u64i
 
 void ref_arg(int &x) {
   int y = x;
diff --git a/clang/test/CIR/CodeGen/bitfields_be.c 
b/clang/test/CIR/CodeGen/bitfields_be.c
index f4f3476d2ef23..730d845928578 100644
--- a/clang/test/CIR/CodeGen/bitfields_be.c
+++ b/clang/test/CIR/CodeGen/bitfields_be.c
@@ -52,12 +52,11 @@ void load(S* s) {
 
 // field 'a'
 // CIR: cir.func {{.*}} @load
-// CIR:    %[[PTR0:.*]] = cir.alloca !cir.ptr<!rec_S>, 
!cir.ptr<!cir.ptr<!rec_S>>, ["s", init] {alignment = 8 : i64} loc(#loc35)
-// CIR:    %[[CONST1:.*]] = cir.const #cir.int<4> : !s32i
-// CIR:    %[[MIN1:.*]] = cir.unary(minus, %[[CONST1]]) nsw : !s32i, !s32i
+// CIR:    %[[PTR0:.*]] = cir.alloca !cir.ptr<!rec_S>, 
!cir.ptr<!cir.ptr<!rec_S>>, ["s", init]
+// CIR:    %[[CONST1:.*]] = cir.const #cir.int<-4> : !s32i
 // CIR:    %[[VAL0:.*]] = cir.load align(8) %[[PTR0]] : 
!cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
 // CIR:    %[[GET0:.*]] = cir.get_member %[[VAL0]][0] {name = "a"} : 
!cir.ptr<!rec_S> -> !cir.ptr<!u32i>
-// CIR:    %[[SET0:.*]] = cir.set_bitfield align(4) (#bfi_a, %[[GET0]] : 
!cir.ptr<!u32i>, %[[MIN1]] : !s32i) -> !s32i
+// CIR:    %[[SET0:.*]] = cir.set_bitfield align(4) (#bfi_a, %[[GET0]] : 
!cir.ptr<!u32i>, %[[CONST1]] : !s32i) -> !s32i
 
 // LLVM: define dso_local void @load{{.*}}{{.*}}
 // LLVM:   %[[PTR0:.*]] = load ptr
@@ -94,11 +93,10 @@ void load(S* s) {
 // OGCG:   store i32 %[[OR1]], ptr %[[PTR1]], align 4
 
 // field 'c'
-// CIR:    %[[CONST3:.*]] = cir.const #cir.int<12345> : !s32i
-// CIR:    %[[MIN2:.*]] = cir.unary(minus, %[[CONST3]]) nsw : !s32i, !s32i
+// CIR:    %[[CONST3:.*]] = cir.const #cir.int<-12345> : !s32i
 // CIR:    %[[VAL2:.*]] = cir.load align(8) %[[PTR0]] : 
!cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
 // CIR:    %[[GET2:.*]] = cir.get_member %[[VAL2]][0] {name = "c"} : 
!cir.ptr<!rec_S> -> !cir.ptr<!u32i>
-// CIR:    %[[SET2:.*]] = cir.set_bitfield align(4) (#bfi_c, %[[GET2]] : 
!cir.ptr<!u32i>, %[[MIN2]] : !s32i) -> !s32i
+// CIR:    %[[SET2:.*]] = cir.set_bitfield align(4) (#bfi_c, %[[GET2]] : 
!cir.ptr<!u32i>, %[[CONST3]] : !s32i) -> !s32i
 
 // LLVM:  %[[PTR2:.*]] = load ptr
 // LLVM:  %[[GET2:.*]] = getelementptr %struct.S, ptr  %[[PTR2]], i32 0, i32 0
diff --git a/clang/test/CIR/CodeGen/goto.cpp b/clang/test/CIR/CodeGen/goto.cpp
index 4b825d619c221..e9ef9fd81f160 100644
--- a/clang/test/CIR/CodeGen/goto.cpp
+++ b/clang/test/CIR/CodeGen/goto.cpp
@@ -24,9 +24,8 @@ int shouldNotGenBranchRet(int x) {
 // CIR:    cir.return [[RET]] : !s32i
 // CIR:  ^bb2:
 // CIR:    cir.label "err"
-// CIR:    [[ONE:%.*]] = cir.const #cir.int<1> : !s32i
-// CIR:    [[MINUS:%.*]] = cir.unary(minus, [[ONE]]) nsw : !s32i, !s32i
-// CIR:    cir.store [[MINUS]], [[RETVAL]] : !s32i, !cir.ptr<!s32i>
+// CIR:    [[MINUS_ONE:%.*]] = cir.const #cir.int<-1> : !s32i
+// CIR:    cir.store [[MINUS_ONE]], [[RETVAL]] : !s32i, !cir.ptr<!s32i>
 // CIR:    cir.br ^bb1
 
 // LLVM: define dso_local i32 @_Z21shouldNotGenBranchReti
diff --git a/clang/test/CIR/CodeGen/pointers.cpp 
b/clang/test/CIR/CodeGen/pointers.cpp
index 68eea6210f1dd..b07c1b57c127d 100644
--- a/clang/test/CIR/CodeGen/pointers.cpp
+++ b/clang/test/CIR/CodeGen/pointers.cpp
@@ -9,14 +9,17 @@ void foo(int *iptr, char *cptr, unsigned ustride) {
   cptr + 3;
   // CHECK: %[[#STRIDE:]] = cir.const #cir.int<3> : !s32i
   // CHECK: cir.ptr_stride %{{.+}}, %[[#STRIDE]] : (!cir.ptr<!s8i>, !s32i) -> 
!cir.ptr<!s8i>
-  iptr - 2;
-  // CHECK: %[[#STRIDE:]] = cir.const #cir.int<2> : !s32i
-  // CHECK: %[[#NEGSTRIDE:]] = cir.unary(minus, %[[#STRIDE]]) : !s32i, !s32i
-  // CHECK: cir.ptr_stride %{{.+}}, %[[#NEGSTRIDE]] : (!cir.ptr<!s32i>, !s32i) 
-> !cir.ptr<!s32i>
-  cptr - 3;
-  // CHECK: %[[#STRIDE:]] = cir.const #cir.int<3> : !s32i
-  // CHECK: %[[#NEGSTRIDE:]] = cir.unary(minus, %[[#STRIDE]]) : !s32i, !s32i
-  // CHECK: cir.ptr_stride %{{.+}}, %[[#NEGSTRIDE]] : (!cir.ptr<!s8i>, !s32i) 
-> !cir.ptr<!s8i>
+
+  // We need to assign to a temporary in these cases because otherwise
+  // constant folding of the unary minus for thenegative stride value also
+  // triggers erasing the unused result of the ptr_stride operation.
+  int* iptr2 = iptr - 2;
+  // CHECK: %[[#STRIDE:]] = cir.const #cir.int<-2> : !s32i
+  // CHECK: cir.ptr_stride %{{.+}}, %[[#STRIDE]] : (!cir.ptr<!s32i>, !s32i) -> 
!cir.ptr<!s32i>
+  char* cptr2 = cptr - 3;
+
+  // CHECK: %[[#STRIDE:]] = cir.const #cir.int<-3> : !s32i
+  // CHECK: cir.ptr_stride %{{.+}}, %[[#STRIDE]] : (!cir.ptr<!s8i>, !s32i) -> 
!cir.ptr<!s8i>
   iptr + ustride;
   // CHECK: %[[#STRIDE:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!u32i>, !u32i
   // CHECK: cir.ptr_stride %{{.+}}, %[[#STRIDE]] : (!cir.ptr<!s32i>, !u32i) -> 
!cir.ptr<!s32i>
diff --git a/clang/test/CIR/CodeGen/switch.cpp 
b/clang/test/CIR/CodeGen/switch.cpp
index a7468954665c0..3449645643d82 100644
--- a/clang/test/CIR/CodeGen/switch.cpp
+++ b/clang/test/CIR/CodeGen/switch.cpp
@@ -1218,9 +1218,8 @@ int sw_return_multi_cases(int x) {
 // CIR-NEXT:    cir.return %[[RET2]] : !s32i
 // CIR-NEXT:  }
 // CIR-NEXT:  cir.case(default, []) {
-// CIR:         %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
-// CIR:         %[[NEG:.*]] = cir.unary(minus, %[[ONE]]) {{.*}} : !s32i, !s32i
-// CIR:         cir.store{{.*}} %[[NEG]], %{{.*}} : !s32i, !cir.ptr<!s32i>
+// CIR:         %[[MINUS_ONE:.*]] = cir.const #cir.int<-1> : !s32i
+// CIR:         cir.store{{.*}} %[[MINUS_ONE]], %{{.*}} : !s32i, 
!cir.ptr<!s32i>
 // CIR:         %[[RETDEF:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, 
!s32i
 // CIR-NEXT:    cir.return %[[RETDEF]] : !s32i
 // CIR-NEXT:  }
diff --git a/clang/test/CIR/CodeGen/ternary.cpp 
b/clang/test/CIR/CodeGen/ternary.cpp
index 847c0b4a04009..b57cdefdc26ce 100644
--- a/clang/test/CIR/CodeGen/ternary.cpp
+++ b/clang/test/CIR/CodeGen/ternary.cpp
@@ -71,8 +71,7 @@ int foo(int a, int b) {
 // CIR: }) : (!cir.bool) -> !s32i
 // CIR: [[CAST:%.+]] = cir.cast int_to_bool [[TERNARY_RES]] : !s32i -> 
!cir.bool
 // CIR: cir.if [[CAST]] {
-// CIR: [[ONE:%.+]] = cir.const #cir.int<1> : !s32i
-// CIR: [[MINUS_ONE:%.+]] = cir.unary(minus, [[ONE]]) nsw : !s32i, !s32i
+// CIR: [[MINUS_ONE:%.+]] = cir.const #cir.int<-1> : !s32i
 // CIR: cir.store [[MINUS_ONE]], [[RETVAL]] : !s32i, !cir.ptr<!s32i>
 // CIR: [[RETVAL_VAL:%.+]] = cir.load [[RETVAL]] : !cir.ptr<!s32i>, !s32i
 // CIR: cir.return [[RETVAL_VAL]] : !s32i
diff --git a/clang/test/CIR/Lowering/goto.cir b/clang/test/CIR/Lowering/goto.cir
index cd3a57d2e7138..f19fcdd8e8c8d 100644
--- a/clang/test/CIR/Lowering/goto.cir
+++ b/clang/test/CIR/Lowering/goto.cir
@@ -24,14 +24,13 @@ module {
     cir.return %3 : !s32i
   ^bb2:
     cir.label "err"
-    %4 = cir.const #cir.int<1> : !s32i
-    %5 = cir.unary(minus, %4) : !s32i, !s32i
-    cir.store %5, %1 : !s32i, !cir.ptr<!s32i>
+    %4 = cir.const #cir.int<-1> : !s32i
+    cir.store %4, %1 : !s32i, !cir.ptr<!s32i>
     cir.br ^bb1
   }
 
 // MLIR:  llvm.func @gotoFromIf
-// MLIR:    %[[#One:]] = llvm.mlir.constant(1 : i32) : i32
+// MLIR:    %[[#Minus_one:]] = llvm.mlir.constant(-1 : i32) : i32
 // MLIR:    %[[#Zero:]] = llvm.mlir.constant(0 : i32) : i32
 // MLIR:    llvm.cond_br {{.*}}, ^bb[[#COND_YES:]], ^bb[[#COND_NO:]]
 // MLIR:  ^bb[[#COND_YES]]:
@@ -45,8 +44,7 @@ module {
 // MLIR:    %[[#Ret_val:]] = llvm.load %[[#Ret_val_addr]] {alignment = 4 : 
i64} : !llvm.ptr -> i32
 // MLIR:    llvm.return %[[#Ret_val]] : i32
 // MLIR:  ^bb[[#GOTO_BLK]]:
-// MLIR:    %[[#Neg_one:]] = llvm.sub %[[#Zero]], %[[#One]]  : i32
-// MLIR:    llvm.store %[[#Neg_one]], %[[#Ret_val_addr]] {{.*}}: i32, !llvm.ptr
+// MLIR:    llvm.store %[[#Minus_one]], %[[#Ret_val_addr]] {{.*}}: i32, 
!llvm.ptr
 // MLIR:    llvm.br ^bb[[#RETURN]]
 // MLIR: }
 }
diff --git a/clang/test/CIR/Transforms/canonicalize.cir 
b/clang/test/CIR/Transforms/canonicalize.cir
index 4f29fbc273801..cfac73ecdb738 100644
--- a/clang/test/CIR/Transforms/canonicalize.cir
+++ b/clang/test/CIR/Transforms/canonicalize.cir
@@ -7,6 +7,9 @@
 !u32i = !cir.int<u, 32>
 !u64i = !cir.int<u, 64>
 
+#true = #cir.bool<true> : !cir.bool
+#false = #cir.bool<false> : !cir.bool
+
 module {
   cir.func @redundant_br() {
     cir.br ^bb1
@@ -60,12 +63,12 @@ module {
   // CHECK-NEXT:   cir.return
   // CHECK-NEXT: }
 
-  cir.func @unary_not(%arg0: !cir.bool) -> !cir.bool {
+  cir.func @unary_not_not(%arg0: !cir.bool) -> !cir.bool {
     %0 = cir.unary(not, %arg0) : !cir.bool, !cir.bool
     %1 = cir.unary(not, %0) : !cir.bool, !cir.bool
     cir.return %1 : !cir.bool
   }
-  // CHECK:      cir.func{{.*}} @unary_not(%arg0: !cir.bool) -> !cir.bool
+  // CHECK:      cir.func{{.*}} @unary_not_not(%arg0: !cir.bool) -> !cir.bool
   // CHECK-NEXT:   cir.return %arg0 : !cir.bool
 
   cir.func @unary_poison() -> !s32i {
@@ -78,6 +81,186 @@ module {
   // CHECK-NEXT:   cir.return %[[P]] : !s32i
   // CHECK-NEXT: }
 
+  cir.func @unary_not_true() -> !cir.bool {
+    %0 = cir.const #true
+    %1 = cir.unary(not, %0) : !cir.bool, !cir.bool
+    cir.return %1 : !cir.bool
+  }
+  // CHECK:      cir.func{{.*}} @unary_not_true() -> !cir.bool
+  // CHECK-NEXT:   %[[FALSE:.*]] = cir.const #false
+  // CHECK-NEXT:   cir.return %[[FALSE]] : !cir.bool
+
+  cir.func @unary_not_false() -> !cir.bool {
+    %0 = cir.const #false
+    %1 = cir.unary(not, %0) : !cir.bool, !cir.bool
+    cir.return %1 : !cir.bool
+  }
+  // CHECK:      cir.func{{.*}} @unary_not_false() -> !cir.bool
+  // CHECK-NEXT:   %[[FALSE:.*]] = cir.const #true
+  // CHECK-NEXT:   cir.return %[[FALSE]] : !cir.bool
+
+  cir.func @unary_not_int() -> !s32i {
+    %0 = cir.const #cir.int<1> : !s32i
+    %1 = cir.unary(not, %0) : !s32i, !s32i
+    cir.return %1 : !s32i
+  }
+  // CHECK:      cir.func{{.*}} @unary_not_int() -> !s32i
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.int<-2> : !s32i
+  // CHECK-NEXT:   cir.return %[[CONST]] : !s32i
+
+  cir.func @unary_not_uint() -> !u32i {
+    %0 = cir.const #cir.int<1> : !u32i
+    %1 = cir.unary(not, %0) : !u32i, !u32i
+    cir.return %1 : !u32i
+  }
+  // CHECK:      cir.func{{.*}} @unary_not_uint() -> !u32i
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.int<4294967294> : !u32i
+  // CHECK-NEXT:   cir.return %[[CONST]] : !u32i
+
+  cir.func @unary_plus_true() -> !cir.bool {
+    %0 = cir.const #true
+    %1 = cir.unary(plus, %0) : !cir.bool, !cir.bool
+    cir.return %1 : !cir.bool
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_true() -> !cir.bool
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #true
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.bool
+
+  cir.func @unary_plus_false() -> !cir.bool {
+    %0 = cir.const #false
+    %1 = cir.unary(plus, %0) : !cir.bool, !cir.bool
+    cir.return %1 : !cir.bool
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_false() -> !cir.bool
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #false
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.bool
+
+  cir.func @unary_plus_int() -> !s32i {
+    %0 = cir.const #cir.int<1> : !s32i
+    %1 = cir.unary(plus, %0) : !s32i, !s32i
+    cir.return %1 : !s32i
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_int() -> !s32i
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.int<1> : !s32i
+  // CHECK-NEXT:   cir.return %[[CONST]] : !s32i
+
+  cir.func @unary_plus_uint() -> !u32i {
+    %0 = cir.const #cir.int<1> : !u32i
+    %1 = cir.unary(plus, %0) : !u32i, !u32i
+    cir.return %1 : !u32i
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_uint() -> !u32i
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.int<1> : !u32i
+  // CHECK-NEXT:   cir.return %[[CONST]] : !u32i
+
+  cir.func @unary_plus_float() -> !cir.float {
+    %0 = cir.const #cir.fp<1.100000e+00> : !cir.float
+    %1 = cir.unary(plus, %0) : !cir.float, !cir.float
+    cir.return %1 : !cir.float
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_float() -> !cir.float
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<1.100000e+00> : !cir.float
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.float
+
+  cir.func @unary_plus_double() -> !cir.double {
+    %0 = cir.const #cir.fp<1.100000e+00> : !cir.double
+    %1 = cir.unary(plus, %0) : !cir.double, !cir.double
+    cir.return %1 : !cir.double
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_double() -> !cir.double
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<1.100000e+00> : 
!cir.double
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.double
+
+  cir.func @unary_plus_nan() -> !cir.float {
+    %0 = cir.const #cir.fp<0x7F800000> : !cir.float
+    %1 = cir.unary(plus, %0) : !cir.float, !cir.float
+    cir.return %1 : !cir.float
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_nan() -> !cir.float
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<0x7F800000> : !cir.float
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.float
+
+  cir.func @unary_plus_neg_nan() -> !cir.float {
+    %0 = cir.const #cir.fp<0xFF800000> : !cir.float
+    %1 = cir.unary(plus, %0) : !cir.float, !cir.float
+    cir.return %1 : !cir.float
+  }
+  // CHECK:      cir.func{{.*}} @unary_plus_neg_nan() -> !cir.float
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<0xFF800000> : !cir.float
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.float
+
+  cir.func @unary_minus_true() -> !cir.bool {
+    %0 = cir.const #true
+    %1 = cir.unary(minus, %0) : !cir.bool, !cir.bool
+    cir.return %1 : !cir.bool
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_true() -> !cir.bool
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #true
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.bool
+
+  cir.func @unary_minus_false() -> !cir.bool {
+    %0 = cir.const #false
+    %1 = cir.unary(minus, %0) : !cir.bool, !cir.bool
+    cir.return %1 : !cir.bool
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_false() -> !cir.bool
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #false
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.bool
+
+  cir.func @unary_minus_int() -> !s32i {
+    %0 = cir.const #cir.int<1> : !s32i
+    %1 = cir.unary(minus, %0) : !s32i, !s32i
+    cir.return %1 : !s32i
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_int() -> !s32i
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.int<-1> : !s32i
+  // CHECK-NEXT:   cir.return %[[CONST]] : !s32i
+
+  cir.func @unary_minus_uint() -> !u32i {
+    %0 = cir.const #cir.int<1> : !u32i
+    %1 = cir.unary(minus, %0) : !u32i, !u32i
+    cir.return %1 : !u32i
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_uint() -> !u32i
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.int<4294967295> : !u32i
+  // CHECK-NEXT:   cir.return %[[CONST]] : !u32i
+
+  cir.func @unary_minus_float() -> !cir.float {
+    %0 = cir.const #cir.fp<1.100000e+00> : !cir.float
+    %1 = cir.unary(minus, %0) : !cir.float, !cir.float
+    cir.return %1 : !cir.float
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_float() -> !cir.float
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<-1.100000e+00> : 
!cir.float
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.float
+
+  cir.func @unary_minus_double() -> !cir.double {
+    %0 = cir.const #cir.fp<1.100000e+00> : !cir.double
+    %1 = cir.unary(minus, %0) : !cir.double, !cir.double
+    cir.return %1 : !cir.double
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_double() -> !cir.double
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<-1.100000e+00> : 
!cir.double
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.double
+
+  cir.func @unary_minus_nan() -> !cir.float {
+    %0 = cir.const #cir.fp<0x7F800000> : !cir.float
+    %1 = cir.unary(minus, %0) : !cir.float, !cir.float
+    cir.return %1 : !cir.float
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_nan() -> !cir.float
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<0xFF800000> : !cir.float
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.float
+
+  cir.func @unary_minus_neg_nan() -> !cir.float {
+    %0 = cir.const #cir.fp<0xFF800000> : !cir.float
+    %1 = cir.unary(minus, %0) : !cir.float, !cir.float
+    cir.return %1 : !cir.float
+  }
+  // CHECK:      cir.func{{.*}} @unary_minus_neg_nan() -> !cir.float
+  // CHECK-NEXT:   %[[CONST:.*]] = cir.const #cir.fp<0x7F800000> : !cir.float
+  // CHECK-NEXT:   cir.return %[[CONST]] : !cir.float
+
   cir.func @cast1(%arg0: !cir.bool) -> !cir.bool {
     %0 = cir.cast bool_to_int %arg0 : !cir.bool -> !s32i
     %1 = cir.cast int_to_bool %0 : !s32i -> !ci...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/174882
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to