Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -2712,8 +2712,10 @@ // LLVM requires the LHS and RHS to be the same type: promote or truncate the // RHS to the same size as the LHS. Value *RHS = Ops.RHS; - if (Ops.LHS->getType() != RHS->getType()) - RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + if (Ops.LHS->getType() != RHS->getType()) { + bool isSigned = dyn_cast(Ops.E)->getRHS()->getType().getTypePtr()->isSignedIntegerType(); + RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), isSigned, "sh_prom"); + } bool SanitizeBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) && Ops.Ty->hasSignedIntegerRepresentation(); Index: test/CodeGen/rhs_signed_check.c =================================================================== --- test/CodeGen/rhs_signed_check.c +++ test/CodeGen/rhs_signed_check.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s + +long long shl_long_short(long long arg1, short arg2) { + return (arg1 << arg2); +// CHECK: %conv = sext i16 %1 to i32 +// CHECK: %sh_prom = sext i32 %conv to i64 +// CHECK: %shl = shl i64 %0, %sh_prom +}