summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp10
-rw-r--r--clang/test/CodeGen/ppc-vector-compare.cc11
2 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index fba9574b021..68a2f13e70b 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3214,6 +3214,16 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
Value *CR6Param = Builder.getInt32(CR6);
llvm::Function *F = CGF.CGM.getIntrinsic(ID);
Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
+
+ // The result type of intrinsic may not be same as E->getType().
+ // If E->getType() is not BoolTy, EmitScalarConversion will do the
+ // conversion work. If E->getType() is BoolTy, EmitScalarConversion will
+ // do nothing, if ResultTy is not i1 at the same time, it will cause
+ // crash later.
+ llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
+ if (ResultTy->getBitWidth() > 1 &&
+ E->getType() == CGF.getContext().BoolTy)
+ Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
E->getExprLoc());
}
diff --git a/clang/test/CodeGen/ppc-vector-compare.cc b/clang/test/CodeGen/ppc-vector-compare.cc
new file mode 100644
index 00000000000..43fbf84c6db
--- /dev/null
+++ b/clang/test/CodeGen/ppc-vector-compare.cc
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64-unknown-unknown -emit-llvm %s \
+// RUN: -o - | FileCheck %s
+
+#include <altivec.h>
+
+// CHECK-LABEL: @_Z5test1Dv8_tS_
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+bool test1(vector unsigned short v1, vector unsigned short v2) {
+ return v1 == v2;
+}
+
OpenPOWER on IntegriCloud