[llvm] [InstCombine] Fold copysign(floor(fabs(X)), X) to trunc(X) (PR #200836)

Aayush Shrivastava via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 12:54:17 PDT 2026


================
@@ -348,6 +348,33 @@ define double @copysign_floor_fabs_to_trunc_fmf(double %x) {
   ret double %result
 }
 
+; Fold applies without any FMF -- copysign's implicit fabs handles NaN.
+define double @copysign_floor_fabs_to_trunc_no_fmf(double %x) {
+; CHECK-LABEL: @copysign_floor_fabs_to_trunc_no_fmf(
+; CHECK-NEXT:    [[RESULT:%.*]] = call double @llvm.trunc.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[RESULT1:%.*]] = call double @llvm.copysign.f64(double [[RESULT]], double [[X]])
+; CHECK-NEXT:    ret double [[RESULT1]]
+;
+  %abs = call double @llvm.fabs.f64(double %x)
+  %fl = call double @llvm.floor.f64(double %abs)
+  %result = call double @llvm.copysign.f64(double %fl, double %x)
+  ret double %result
+}
+
+; stripSignOnlyFPOps folds fabs(fneg(X)) inside floor.
+define double @copysign_floor_fabs_fneg_to_trunc(double %x) {
+; CHECK-LABEL: @copysign_floor_fabs_fneg_to_trunc(
+; CHECK-NEXT:    [[RESULT:%.*]] = call double @llvm.trunc.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[RESULT1:%.*]] = call double @llvm.copysign.f64(double [[RESULT]], double [[X]])
+; CHECK-NEXT:    ret double [[RESULT1]]
+;
+  %neg = fneg double %x
+  %abs = call double @llvm.fabs.f64(double %neg)
----------------
iamaayushrivastava wrote:

Done! Replaced `fabs(fneg(X))` with the more realistic `fneg(fabs(X))` as a negative test, and added a `fabs(copysign(X, Y))` positive test.

https://github.com/llvm/llvm-project/pull/200836


More information about the llvm-commits mailing list