r347527 - [CodeGen] translate MS rotate builtins to LLVM funnel-shift intrinsics

Sanjay Patel via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 25 09:53:16 PST 2018


Author: spatel
Date: Sun Nov 25 09:53:16 2018
New Revision: 347527

URL: http://llvm.org/viewvc/llvm-project?rev=347527&view=rev
Log:
[CodeGen] translate MS rotate builtins to LLVM funnel-shift intrinsics

This was originally part of:
D50924

and should resolve PR37387:
https://bugs.llvm.org/show_bug.cgi?id=37387

...but it was reverted because some bots using a gcc host compiler 
would crash for unknown reasons with this included in the patch. 
Trying again now to see if that's still a problem.

Modified:
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=347527&r1=347526&r2=347527&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sun Nov 25 09:53:16 2018
@@ -1820,46 +1820,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(
                                      "cast");
     return RValue::get(Result);
   }
-  case Builtin::BI_rotr8:
-  case Builtin::BI_rotr16:
-  case Builtin::BI_rotr:
-  case Builtin::BI_lrotr:
-  case Builtin::BI_rotr64: {
-    Value *Val = EmitScalarExpr(E->getArg(0));
-    Value *Shift = EmitScalarExpr(E->getArg(1));
-
-    llvm::Type *ArgType = Val->getType();
-    Shift = Builder.CreateIntCast(Shift, ArgType, false);
-    unsigned ArgWidth = ArgType->getIntegerBitWidth();
-    Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
-
-    Value *RightShiftAmt = Builder.CreateAnd(Shift, Mask);
-    Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt);
-    Value *LeftShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask);
-    Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt);
-    Value *Result = Builder.CreateOr(LeftShifted, RightShifted);
-    return RValue::get(Result);
-  }
-  case Builtin::BI_rotl8:
-  case Builtin::BI_rotl16:
-  case Builtin::BI_rotl:
-  case Builtin::BI_lrotl:
-  case Builtin::BI_rotl64: {
-    Value *Val = EmitScalarExpr(E->getArg(0));
-    Value *Shift = EmitScalarExpr(E->getArg(1));
-
-    llvm::Type *ArgType = Val->getType();
-    Shift = Builder.CreateIntCast(Shift, ArgType, false);
-    unsigned ArgWidth = ArgType->getIntegerBitWidth();
-    Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
-
-    Value *LeftShiftAmt = Builder.CreateAnd(Shift, Mask);
-    Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt);
-    Value *RightShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask);
-    Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt);
-    Value *Result = Builder.CreateOr(LeftShifted, RightShifted);
-    return RValue::get(Result);
-  }
   case Builtin::BI__builtin_unpredictable: {
     // Always return the argument of __builtin_unpredictable. LLVM does not
     // handle this builtin. Metadata for this builtin should be added directly
@@ -1918,12 +1878,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(
   case Builtin::BI__builtin_rotateleft16:
   case Builtin::BI__builtin_rotateleft32:
   case Builtin::BI__builtin_rotateleft64:
+  case Builtin::BI_rotl8: // Microsoft variants of rotate left
+  case Builtin::BI_rotl16:
+  case Builtin::BI_rotl:
+  case Builtin::BI_lrotl:
+  case Builtin::BI_rotl64:
     return emitRotate(E, false);
 
   case Builtin::BI__builtin_rotateright8:
   case Builtin::BI__builtin_rotateright16:
   case Builtin::BI__builtin_rotateright32:
   case Builtin::BI__builtin_rotateright64:
+  case Builtin::BI_rotr8: // Microsoft variants of rotate right
+  case Builtin::BI_rotr16:
+  case Builtin::BI_rotr:
+  case Builtin::BI_lrotr:
+  case Builtin::BI_rotr64:
     return emitRotate(E, true);
 
   case Builtin::BI__builtin_constant_p: {

Modified: cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c?rev=347527&r1=347526&r2=347527&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c (original)
+++ cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c Sun Nov 25 09:53:16 2018
@@ -30,66 +30,36 @@ unsigned char test_rotl8(unsigned char v
   return _rotl8(value, shift);
 }
 // CHECK: i8 @test_rotl8
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i8 [[SHIFT:%[0-9]+]], 7
-// CHECK:   [[HIGH:%[0-9]+]] = shl i8 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i8 0, [[SHIFT]]
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i8 [[NEGATE]], 7
-// CHECK:   [[LOW:%[0-9]+]] = lshr i8 [[VALUE]], [[RSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i8 [[HIGH]], [[LOW]]
-// CHECK:   ret i8 [[RESULT]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+// CHECK:   ret i8 [[R]]
 
 unsigned short test_rotl16(unsigned short value, unsigned char shift) {
   return _rotl16(value, shift);
 }
 // CHECK: i16 @test_rotl16
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i16 [[SHIFT:%[0-9]+]], 15
-// CHECK:   [[HIGH:%[0-9]+]] = shl i16 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i16 0, [[SHIFT]]
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i16 [[NEGATE]], 15
-// CHECK:   [[LOW:%[0-9]+]] = lshr i16 [[VALUE]], [[RSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i16 [[HIGH]], [[LOW]]
-// CHECK:   ret i16 [[RESULT]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK:   ret i16 [[R]]
 
 unsigned int test_rotl(unsigned int value, int shift) {
   return _rotl(value, shift);
 }
 // CHECK: i32 @test_rotl
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK:   [[HIGH:%[0-9]+]] = shl i32 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK:   [[LOW:%[0-9]+]] = lshr i32 [[VALUE]], [[RSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK:   ret i32 [[RESULT]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK:   ret i32 [[R]]
 
 unsigned LONG test_lrotl(unsigned LONG value, int shift) {
   return _lrotl(value, shift);
 }
 // CHECK-32BIT-LONG: i32 @test_lrotl
-// CHECK-32BIT-LONG:   [[LSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK-32BIT-LONG:   [[HIGH:%[0-9]+]] = shl i32 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK-32BIT-LONG:   [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK-32BIT-LONG:   [[RSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK-32BIT-LONG:   [[LOW:%[0-9]+]] = lshr i32 [[VALUE]], [[RSHIFT]]
-// CHECK-32BIT-LONG:   [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK-32BIT-LONG:   ret i32 [[RESULT]]
-// CHECK-32BIT-LONG  }
+// CHECK-32BIT-LONG:   [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK-32BIT-LONG:   ret i32 [[R]]
 
 unsigned __int64 test_rotl64(unsigned __int64 value, int shift) {
   return _rotl64(value, shift);
 }
 // CHECK: i64 @test_rotl64
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i64 [[SHIFT:%[0-9]+]], 63
-// CHECK:   [[HIGH:%[0-9]+]] = shl i64 [[VALUE:%[0-9]+]], [[LSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i64 0, [[SHIFT]]
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i64 [[NEGATE]], 63
-// CHECK:   [[LOW:%[0-9]+]] = lshr i64 [[VALUE]], [[RSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i64 [[HIGH]], [[LOW]]
-// CHECK:   ret i64 [[RESULT]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK:   ret i64 [[R]]
 
 // rotate right
 
@@ -97,61 +67,34 @@ unsigned char test_rotr8(unsigned char v
   return _rotr8(value, shift);
 }
 // CHECK: i8 @test_rotr8
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i8 [[SHIFT:%[0-9]+]], 7
-// CHECK:   [[LOW:%[0-9]+]] = lshr i8 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i8 0, [[SHIFT]]
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i8 [[NEGATE]], 7
-// CHECK:   [[HIGH:%[0-9]+]] = shl i8 [[VALUE]], [[LSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i8 [[HIGH]], [[LOW]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+// CHECK:   ret i8 [[R]]
 
 unsigned short test_rotr16(unsigned short value, unsigned char shift) {
   return _rotr16(value, shift);
 }
 // CHECK: i16 @test_rotr16
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i16 [[SHIFT:%[0-9]+]], 15
-// CHECK:   [[LOW:%[0-9]+]] = lshr i16 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i16 0, [[SHIFT]]
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i16 [[NEGATE]], 15
-// CHECK:   [[HIGH:%[0-9]+]] = shl i16 [[VALUE]], [[LSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i16 [[HIGH]], [[LOW]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK:   ret i16 [[R]]
 
 unsigned int test_rotr(unsigned int value, int shift) {
   return _rotr(value, shift);
 }
 // CHECK: i32 @test_rotr
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK:   [[LOW:%[0-9]+]] = lshr i32 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK:   [[HIGH:%[0-9]+]] = shl i32 [[VALUE]], [[LSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK:   ret i32 [[RESULT]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK:   ret i32 [[R]]
 
 unsigned LONG test_lrotr(unsigned LONG value, int shift) {
   return _lrotr(value, shift);
 }
 // CHECK-32BIT-LONG: i32 @test_lrotr
-// CHECK-32BIT-LONG:   [[RSHIFT:%[0-9]+]] = and i32 [[SHIFT:%[0-9]+]], 31
-// CHECK-32BIT-LONG:   [[LOW:%[0-9]+]] = lshr i32 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK-32BIT-LONG:   [[NEGATE:%[0-9]+]] = sub i32 0, [[SHIFT]]
-// CHECK-32BIT-LONG:   [[LSHIFT:%[0-9]+]] = and i32 [[NEGATE]], 31
-// CHECK-32BIT-LONG:   [[HIGH:%[0-9]+]] = shl i32 [[VALUE]], [[LSHIFT]]
-// CHECK-32BIT-LONG:   [[RESULT:%[0-9]+]] = or i32 [[HIGH]], [[LOW]]
-// CHECK-32BIT-LONG:   ret i32 [[RESULT]]
-// CHECK-32BIT-LONG  }
+// CHECK-32BIT-LONG:   [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK-32BIT-LONG:   ret i32 [[R]]
 
 unsigned __int64 test_rotr64(unsigned __int64 value, int shift) {
   return _rotr64(value, shift);
 }
 // CHECK: i64 @test_rotr64
-// CHECK:   [[RSHIFT:%[0-9]+]] = and i64 [[SHIFT:%[0-9]+]], 63
-// CHECK:   [[LOW:%[0-9]+]] = lshr i64 [[VALUE:%[0-9]+]], [[RSHIFT]]
-// CHECK:   [[NEGATE:%[0-9]+]] = sub i64 0, [[SHIFT]]
-// CHECK:   [[LSHIFT:%[0-9]+]] = and i64 [[NEGATE]], 63
-// CHECK:   [[HIGH:%[0-9]+]] = shl i64 [[VALUE]], [[LSHIFT]]
-// CHECK:   [[RESULT:%[0-9]+]] = or i64 [[HIGH]], [[LOW]]
-// CHECK:   ret i64 [[RESULT]]
-// CHECK  }
+// CHECK:   [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK:   ret i64 [[R]]
+




More information about the cfe-commits mailing list