[llvm] [InstCombine] Fix type mismatch between cond and value in `foldSelectToCopysign` (PR #76343)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 24 15:10:53 PST 2023
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/76343
This patch fixes the miscompilation when we try to bitcast a floating point vector into an integer scalar.
>From ef850b7689886cbff77952346765f3312ce6a46f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 25 Dec 2023 07:04:00 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/select.ll | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 7583a75385a769..14b7021cc98962 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -1735,6 +1735,20 @@ define float @copysign_type_mismatch(double %x) {
; Negative test
+; FIXME: It is a miscompilation.
+define <2 x float> @copysign_type_mismatch2(<2 x float> %x) {
+; CHECK-LABEL: @copysign_type_mismatch2(
+; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]])
+; CHECK-NEXT: ret <2 x float> [[R]]
+;
+ %i = bitcast <2 x float> %x to i64
+ %ispos = icmp sgt i64 %i, -1
+ %r = select i1 %ispos, <2 x float> <float 1.0, float 1.0>, <2 x float> <float -1.0, float -1.0>
+ ret <2 x float> %r
+}
+
+; Negative test
+
define float @copysign_wrong_cmp(float %x) {
; CHECK-LABEL: @copysign_wrong_cmp(
; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32
>From 38f1af4b69fc6fbf5c6098eafa61143aac7e7ef4 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 25 Dec 2023 07:06:05 +0800
Subject: [PATCH 2/2] [InstCombine] Fix type mismatch between cond and value in
`foldSelectToCopysign`
---
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 3 +++
llvm/test/Transforms/InstCombine/select.ll | 5 +++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 20bf00344b144b..3c6ce450c5bcfa 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2363,6 +2363,9 @@ static Instruction *foldSelectToCopysign(SelectInst &Sel,
Value *FVal = Sel.getFalseValue();
Type *SelType = Sel.getType();
+ if (ICmpInst::makeCmpResultType(TVal->getType()) != Cond->getType())
+ return nullptr;
+
// Match select ?, TC, FC where the constants are equal but negated.
// TODO: Generalize to handle a negated variable operand?
const APFloat *TC, *FC;
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 14b7021cc98962..94aa012f868015 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -1735,10 +1735,11 @@ define float @copysign_type_mismatch(double %x) {
; Negative test
-; FIXME: It is a miscompilation.
define <2 x float> @copysign_type_mismatch2(<2 x float> %x) {
; CHECK-LABEL: @copysign_type_mismatch2(
-; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]])
+; CHECK-NEXT: [[I:%.*]] = bitcast <2 x float> [[X:%.*]] to i64
+; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1
+; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float -1.000000e+00, float -1.000000e+00>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%i = bitcast <2 x float> %x to i64
More information about the llvm-commits
mailing list