Skip to content

Commit 605c53b

Browse files
committed
[CIR][Lowering] Fix Vector Comparison Lowering with -fno-signed-char/unsigned operand
1 parent 59ccba6 commit 605c53b

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,15 @@ mlir::LogicalResult CIRToLLVMVecCreateOpLowering::matchAndRewrite(
19851985
return mlir::success();
19861986
}
19871987

1988+
static bool isCIRZeroVector(mlir::Value value) {
1989+
if (auto constantOp = value.getDefiningOp<cir::ConstantOp>()) {
1990+
if (auto zeroAttr = mlir::dyn_cast<cir::ZeroAttr>(constantOp.getValue())) {
1991+
return true;
1992+
}
1993+
}
1994+
return false;
1995+
}
1996+
19881997
mlir::LogicalResult CIRToLLVMVecCmpOpLowering::matchAndRewrite(
19891998
cir::VecCmpOp op, OpAdaptor adaptor,
19901999
mlir::ConversionPatternRewriter &rewriter) const {
@@ -1993,9 +2002,16 @@ mlir::LogicalResult CIRToLLVMVecCmpOpLowering::matchAndRewrite(
19932002
auto elementType = elementTypeIfVector(op.getLhs().getType());
19942003
mlir::Value bitResult;
19952004
if (auto intType = mlir::dyn_cast<cir::IntType>(elementType)) {
2005+
2006+
bool shouldUseSigned = intType.isSigned();
2007+
// Special treatment For sign-bit extraction patterns (lt comparison with
2008+
// zero), always use signed comparison to preserve the semantic intent
2009+
if (op.getKind() == cir::CmpOpKind::lt && isCIRZeroVector(op.getRhs())) {
2010+
shouldUseSigned = true;
2011+
}
19962012
bitResult = rewriter.create<mlir::LLVM::ICmpOp>(
19972013
op.getLoc(),
1998-
convertCmpKindToICmpPredicate(op.getKind(), intType.isSigned()),
2014+
convertCmpKindToICmpPredicate(op.getKind(), shouldUseSigned),
19992015
adaptor.getLhs(), adaptor.getRhs());
20002016
} else if (mlir::isa<cir::FPTypeInterface>(elementType)) {
20012017
bitResult = rewriter.create<mlir::LLVM::FCmpOp>(

clang/test/CIR/Lowering/vec-cmp.cir

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
!s16i = !cir.int<s, 16>
55
!u16i = !cir.int<u, 16>
6+
!u8i = !cir.int<u, 8>
67

78
cir.func @vec_cmp(%0: !cir.vector<!s16i x 16>, %1: !cir.vector<!s16i x 16>) -> () {
89
%2 = cir.vec.cmp(lt, %0, %1) : !cir.vector<!s16i x 16>, !cir.vector<!cir.int<u, 1> x 16>
@@ -14,3 +15,16 @@ cir.func @vec_cmp(%0: !cir.vector<!s16i x 16>, %1: !cir.vector<!s16i x 16>) -> (
1415
// MLIR-NEXT: %{{[0-9]+}} = llvm.icmp "slt" %arg0, %arg1 : vector<16xi16>
1516
// MLIR-NEXT: %{{[0-9]+}} = llvm.bitcast %{{[0-9]+}} : vector<16xi1> to i16
1617
// MLIR-NEXT: llvm.return
18+
19+
20+
cir.func @vec_cmp_zero(%0: !cir.vector<!u8i x 16>) -> () {
21+
%1 = cir.const #cir.zero : !cir.vector<!u8i x 16>
22+
%2 = cir.vec.cmp(lt, %0, %1) : !cir.vector<!u8i x 16>, !cir.vector<!cir.int<u, 1> x 16>
23+
%3 = cir.cast(bitcast, %2 : !cir.vector<!cir.int<u, 1> x 16>), !cir.int<u, 16>
24+
25+
cir.return
26+
}
27+
28+
// MLIR: llvm.func @vec_cmp_zero
29+
// MLIR: %{{[0-9]+}} = llvm.icmp "slt" %arg0, %{{[0-9]+}} : vector<16xi8>
30+
// MLIR-NEXT: %{{[0-9]+}} = llvm.bitcast %{{[0-9]+}} : vector<16xi1> to i16

0 commit comments

Comments
 (0)