diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -189,18 +189,21 @@ template ExtValue genval(const Fortran::evaluate::Negate> &op) { - TODO(getLoc(), "genval Negate integer"); + mlir::Value input = genunbox(op.left()); + // Like LLVM, integer negation is the binary op "0 - value" + mlir::Value zero = genIntegerConstant(builder.getContext(), 0); + return builder.create(getLoc(), zero, input); } template ExtValue genval(const Fortran::evaluate::Negate> &op) { - TODO(getLoc(), "genval Negate real"); + return builder.create(getLoc(), genunbox(op.left())); } template ExtValue genval(const Fortran::evaluate::Negate> &op) { - TODO(getLoc(), "genval Negate complex"); + return builder.create(getLoc(), genunbox(op.left())); } #undef GENBIN diff --git a/flang/test/Lower/assignment.f90 b/flang/test/Lower/assignment.f90 --- a/flang/test/Lower/assignment.f90 +++ b/flang/test/Lower/assignment.f90 @@ -22,3 +22,46 @@ ! CHECK: %[[B_VAL:.*]] = fir.load %arg1 : !fir.ref ! CHECK: %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i64) -> i32 ! CHECK: fir.store %[[B_CONV]] to %[[A]] : !fir.ref + +integer function negi(a) + integer :: a + negi = -a +end + +! CHECK-LABEL: func @_QPnegi( +! CHECK-SAME: %[[A:.*]]: !fir.ref {fir.bindc_name = "a"}) -> i32 { +! CHECK: %[[FCTRES:.*]] = fir.alloca i32 {bindc_name = "negi", uniq_name = "_QFnegiEnegi"} +! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref +! CHECK: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK: %[[NEG:.*]] = arith.subi %[[C0]], %[[A_VAL]] : i32 +! CHECK: fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref +! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref +! CHECK: return %[[RET]] : i32 + +real function negr(a) + real :: a + negr = -a +end + +! CHECK-LABEL: func @_QPnegr( +! CHECK-SAME: %[[A:.*]]: !fir.ref {fir.bindc_name = "a"}) -> f32 { +! CHECK: %[[FCTRES:.*]] = fir.alloca f32 {bindc_name = "negr", uniq_name = "_QFnegrEnegr"} +! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref +! CHECK: %[[NEG:.*]] = arith.negf %[[A_VAL]] : f32 +! CHECK: fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref +! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref +! CHECK: return %[[RET]] : f32 + +complex function negc(a) + complex :: a + negc = -a +end + +! CHECK-LABEL: func @_QPnegc( +! CHECK-SAME: %[[A:.*]]: !fir.ref> {fir.bindc_name = "a"}) -> !fir.complex<4> { +! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4> {bindc_name = "negc", uniq_name = "_QFnegcEnegc"} +! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref> +! CHECK: %[[NEG:.*]] = fir.negc %[[A_VAL]] : !fir.complex<4> +! CHECK: fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref> +! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref> +! CHECK: return %[[RET]] : !fir.complex<4>